componentDidMount和构造函数

问题描述 投票:5回答:1
 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
             })
          })
    }
reactjs asynchronous callback components es6-promise
1个回答
6
投票

问题是,当您在constructor中放置异步请求时,promise可能会在render阶段执行后被解析,此时this.state为null并且因为您只是分配

this.state = {
    array: arr
}

这不会导致重新渲染,因此组件不会反映变化。说过你应该把你的异步请求放在你第二次尝试中提到的componentDidMount中,并且因为你在那里调用setState,触发了re-render并且状态反映在render

© www.soinside.com 2019 - 2024. All rights reserved.