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
})
})
}
问题是,当您在constructor
中放置异步请求时,promise
可能会在render
阶段执行后被解析,此时this.state为null并且因为您只是分配
this.state = {
array: arr
}
这不会导致重新渲染,因此组件不会反映变化。说过你应该把你的异步请求放在你第二次尝试中提到的componentDidMount
中,并且因为你在那里调用setState
,触发了re-render
并且状态反映在render
中