首先声明这里只讨论类组件
这里说的网络请求指页面初始化的获取数据
componentDidMount无疑是最佳选择,但是为什么不用componentWillMount或者constructor?
这里要先说下:
组件挂载
组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:
- constructor()
- static getDerivedStateFromProps()
- render()
- componentDidMount()
不在componentWillMount中调用网络请求的原因显而易见:
- 此声明周期将被废弃,可用新的声明周期getDerivedStateFromProps代替
- getDerivedStateFromProps导致的re-render受state和props的改变而驱动,因此会多次重复调用
- 如果使用了服务端渲染,使用此生命周期,fetchData会执行两次,一次在服务端,一次在客户端,使用componentDidMount没有此问题
那可以在constructor中调用网络请求并setState吗?
如测试代码:
constructor(props){
super(props);
this.state = {
num: 1
}
// 模拟异步操作 更新state
setTimeout(()=>{
this.setState({num:4})
},1000)
}
render(){
return <h1>{this.state.num}</h1>
}
页面会更新,最后显示为4,看上去和用componentDidMount没什么区别 然而不同的是: ** constructor在组件初始化即render前执行,假如组件树出了一些错误没法正常render,此时仍然会在constructor执行不必要的fetch data操作 **
另外官网也给了使用指南:
通常,在 React 中,构造函数仅用于以下两种情况:
- 通过给 this.state 赋值对象来初始化内部 state。
- 为事件处理函数绑定实例
所以还是正确的api做正确的事