Javascript 在从API接收值之前调用React状态

Javascript 在从API接收值之前调用React状态,javascript,reactjs,api,asynchronous,Javascript,Reactjs,Api,Asynchronous,我试图从API获取数据,并在组件上呈现之前将其置于我的状态 但是,在将任何值放入空状态之前,将一直调用空状态 代码如下: const cookies = new Cookies(); class ProductDetails extends Component { state = {product:null} componentWillMount(){ this.getSelectedProduct() } getSelectedProduct(){ var selecte

我试图从API获取数据,并在组件上呈现之前将其置于我的状态

但是,在将任何值放入空状态之前,将一直调用空状态

代码如下:

const cookies = new Cookies();

class ProductDetails extends Component {

state = {product:null}

componentWillMount(){
    this.getSelectedProduct()
}
getSelectedProduct(){
    var selected = cookies.get('SelectedProduct')
    Axios.get('http://localhost:1002/products/' + selected)
    .then(ok=>{
        console.log(ok.data)
        this.setState({product:ok.data})
        console.log(this.state.product[0].ProductName)
    })
}
renderContent(){
    console.log(this.state.product)
    if(this.state.product !== [] ){
        const {ProductName, ProductPrice, Description, Brand, Color, ScreenSize, RAM, Storage, Stock} = this.state.product[0]
        return([
            ProductName,
            ProductPrice,
            Description, 
            Brand, 
            Color, 
            ScreenSize, 
            RAM, 
            Storage, 
            Stock
        ])
    }
}
render(){
    return(
        <div >
            <h3>{this.renderContent().ProductName}</h3>

        </div>
    )
}
}
export default ProductDetails
const cookies=新cookies();
类ProductDetails扩展组件{
状态={product:null}
组件willmount(){
这个.getSelectedProduct()
}
getSelectedProduct(){
var selected=cookies.get('SelectedProduct')
Axios.get()http://localhost:1002/products/“+已选定)
。然后(确定=>{
console.log(ok.data)
this.setState({product:ok.data})
console.log(此.state.product[0].ProductName)
})
}
renderContent(){
console.log(this.state.product)
if(this.state.product!=[]){
const{ProductName,ProductPrice,Description,Brand,Color,ScreenSize,RAM,Storage,Stock}=this.state.product[0]
返回([
产品名称,
产品价格,
描述
品牌,
颜色
屏幕大小,
内存
存储
股票
])
}
}
render(){
返回(
{this.renderContent().ProductName}
)
}
}
导出默认产品详细信息

这就是React的工作方式–
设置状态
是异步的,它不会阻止组件在设置状态之前呈现,即使您从
组件将装载

render
方法中,检查是否设置了
product
,仅当设置了
renderContent
时才调用它

您可以显示“请稍候”消息或微调器

例如:

render() {
    if (this.state.product === null) {


    return(
        <div >
            <h3>{
                this.state.product === null ? 
                "loading data, please wait" :
                this.renderContent().ProductName
            }</h3>
        </div>
    )
}
render(){
if(this.state.product==null){
返回(
{
this.state.product==null?
“正在加载数据,请稍候:”
此.renderContent().ProductName
}
)
}

请注意:
componentWillMount
已被弃用,并且在较新的React版本中不可用。您应该使用
componentDidMount

我同意前面的回答,即您应该使用初始状态作为模型,因此为状态产品提供一个空数组的值。但是,如果您仍然我想在初始状态下定义
null
,您可以在返回渲染方法之前进行检查

render(){
  if (!Array.isArray(this.state.product) {
    return null // or something else such a loading icon or similar.
  }

  return(
    <div >
      Your rendered content here
      ...
    </div>
  )
}
render(){
if(!Array.isArray(this.state.product){
返回null//或其他类似的加载图标或类似内容。
}
返回(
此处显示您的渲染内容
...
)
}

请参见isArray的参考页:

将条件更改为if(this.state.product&&this.state.product.length){考虑到您的代码乍一看很好,我不是100%了解问题所在。但是
这个.setState
是异步的,所以当您尝试
console.log
第一个产品名称时,它还不存在。如果您认为console.log没有打印正确的值。
setState
是异步的,我也认为是问题是因为setState是异步的。我正在寻找一种解决方法。不,用这种方法更改if-else条件是行不通的。它仍然会给出“undefined”错误。您的代码还可以。您是在设置状态后谈论console.log吗?和
setState()
异步不是问题,它是一项功能。你必须围绕它塑造你的应用行为