componentDidMount和构造函数

Jay*_*ong 8 components asynchronous callback reactjs 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 [{..},{..},{..},{..}]

   }
Run Code Online (Sandbox Code Playgroud)

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

 class ProductsIndex extends Component {

   constructor (props){
     super(props);

     fetch('someUrl')
       .then(res => res.json())
       .then(arr => {
          this.state = {
              array: arr
          }
       })
    }
Run Code Online (Sandbox Code Playgroud)

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

下面的代码是解决方案。谁能解释一下到底有什么区别?

 class ProductsIndex extends Component {

   constructor (props){
     super(props);

     this.state = {
       array: []
     }
   }

   componentDidMount(){
      fetch('someUrl')
         .then(res => res.json())
         .then(arr => {
            this.setState({
                array: arr
             })
          })
    }
Run Code Online (Sandbox Code Playgroud)

Shu*_*tri 10

问题在于,当您在中放置异步请求时constructorpromise可能会在render阶段执行后解决,此时this.state为null,而且因为您只是分配了

this.state = {
    array: arr
}
Run Code Online (Sandbox Code Playgroud)

并且不会导致重新渲染,因此组件不会反映更改。话虽如此,您应该componentDidMount 在第二次尝试中放置提到的异步请求,并且由于您setState在此处进行调用,因此re-render会触发a并在render

  • 请勿:避免引入任何副作用或订阅。不要在构造函数中使用setState()来设置状态。 (2认同)