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
})
})
}
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