componentDidMount和构造函数

时间:2018-03-15 03:42:54

标签: reactjs asynchronous callback components es6-promise

 class ProductsIndex extends Component {

   constructor (props){
     super(props);

     console.log(this) // #1. this logs ProductsIndex component

     fetch('someUrl')
        .then(res => res.json())
        .then(res => console.log(this)) // #2. this logs ProductsIndex component

     fetch('someUrl')
        .then(res => res.json())
        .then(console.log)  // #3. this logs [{..},{..},{..},{..}]
   }


   componentDidMount(){
     fetch('someUrl')
        .then(res => res.json())
        .then(console.log)  // #4. this logs [{..},{..},{..},{..}]

   }

如上面的代码所示,#1和#2都指向相同的 。而且如图所示,#3和#4都返回相同的数组。但是,为什么下面的代码不起作用?

 class ProductsIndex extends Component {

   constructor (props){
     super(props);

     fetch('someUrl')
       .then(res => res.json())
       .then(arr => {
          this.state = {
              array: arr
          }
       })
    }

它抛出一个错误,说 this.state null ,我真的不明白为什么。

以下代码是解决方案。有谁能解释究竟是什么区别?

 class ProductsIndex extends Component {

   constructor (props){
     super(props);

     this.state = {
       array: []
     }
   }

   componentDidMount(){
      fetch('someUrl')
         .then(res => res.json())
         .then(arr => {
            this.setState({
                array: arr
             })
          })
    }

1 个答案:

答案 0 :(得分:6)

问题在于,当您在constructor中放置异步请求时,promise可能会在执行render阶段后解析,此时此.state为空,也是你只需要分配

this.state = {
    array: arr
}

这不会导致重新渲染,因此组件不会反映更改。说过你应该在第二次尝试中提到componentDidMount中的异步请求,并且因为你在那里打setState,会触发re-render并且状态会反映在{{ 1}}