2017-10-07 139 views
1

我试图在componentWillMount数据读取服务器端渲染时警告:阵营:麻烦的setState在componentWillMount

警告:的setState(...):只能更新安装组件。这通常意味着您在服务器上的componentWillMount()之外调用setState()。这是一个没有操作。

这里的代码片段:

async fetchProductsSSR() { 
    var response = await fetch(BACKEND_URL + '/products/', { 
     method: 'GET', 
     headers: { 
      'Accept': 'application/json', 
      'Content-Type': 'application/json', 
     }, 
    }); 

    var result = false; 
    var data = await response.json(); 
    console.log(response.status); 

    if (response.status === 200) { 
    } 
    else { 
     data = []; 
    } 
    return data; 
    } 

    async componentWillMount() { 
    if (!process.browser) { 
     var data = await this.fetchProductsSSR(); 
     this.setState({ 
     product_data: data 
     }); 
    } 
    } 

我敢肯定,数据是正确的之前调用this.setState。

如果硬编码的JSON数据,一切都很好

async componentWillMount() { 
    if (!process.browser) { 
    // var data = await this.fetchProductsSSR(); 

     var data = [ 
     { 
     "name": "Test", 
     } 
     ] 

     this.setState({ 
     product_data: data 
     }); 
    } 
    } 

我不知道什么是错的,请指点, 谢谢。

+2

为什么你不使ajax调用componentDidMount?你必须知道建议在componentDidMount方法中发出ajax请求,因为this.setState将重新渲染组件,并且如果在componentWillMount中创建ajax请求,则组件不会呈现,并且不会有任何更新。 –

+0

上述评论是正确的,但要解决您的问题,只需在定义数据时执行setState,即if(data)this.setState({product_data:data})'。这确保你不会尝试将状态为 –

+0

的未定义值设置为@Kenji,在componentWillMount中获取数据的原因是服务器端呈现。提交给用户时,我需要准备好整个页面。 – winxp1981

回答

1

我贤治的评论同意...你要做的是,在ComponentDidMount ...

https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class

,如果你想显示加载信息,您可以设置负载状态和使用条件渲染功能,如...

constructor(){ 
    this.state={loading:true} 
} 
ComponentDidMount(){ 
//do your async thing and change the state to loading:false 
} 
render(){ 
    if(this.state.loading) 
    return <YourMessage /> 

    return <Something /> 
}