web-dev-qa-db-fra.com

componentDidMount et constructeur

 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 [{..},{..},{..},{..}]

   }

Comme indiqué dans le code ci-dessus, # 1 et # 2 pointent vers le même this . Et aussi comme indiqué, # 3 et # 4 renvoient même tableau. Cependant, pourquoi le code ci-dessous ne fonctionne pas ??

 class ProductsIndex extends Component {

   constructor (props){
     super(props);

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

Cela génère une erreur indiquant que this.state est null et je ne comprends vraiment pas pourquoi.

Le code ci-dessous est la solution. quelqu'un pourrait-il expliquer quelle est exactement la différence?

 class ProductsIndex extends Component {

   constructor (props){
     super(props);

     this.state = {
       array: []
     }
   }

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

Le problème est que lorsque vous placez une demande asynchrone dans constructor, la promise peut être résolue après que la phase render a été exécutée et à ce stade, this.state est nul et aussi depuis vous venez d'assigner

this.state = {
    array: arr
}

et cela ne conduira pas à un nouveau rendu et donc le composant ne reflétera pas le changement. Cela dit, vous devez placer vos demandes asynchrones dans componentDidMount que vous mentionnez lors de votre deuxième tentative, et puisque vous appelez setState là, un re-render est déclenché et l'état est reflété dans render

8
Shubham Khatri