在这个演讲 https://reactjs.org/docs/hooks-intro.html 演讲者编写类似于下面的代码:
class SomeComponent extends React.Component {
constructor(props){
super(props)
this.handleResize.bind(this)
}
handleResize(){
//do something with window.innerWidth
}
componentDidMount(){
window.addEventListener('resize',this.handleResize)
}
}
为什么window.addEventListener
部件在组件DidMount中?一定是吗?
从谈话的语气中,我觉得这种情况很常见。
我对反应相当陌生,我也会将浏览器 api 事件订阅放在构造函数中。
有什么优势可以躲避为什么把这个window.addEventListener
放在组件DidMount中?还是只是出于可读性目的?
对我来说,这很简单。
首先,您只希望 api 调用或事件侦听器只调用/初始化一次,componentDidMount()
和constructor
保证每个挂载的组件只运行一次。
但是,我不会将 api 放在构造函数中,因为如果您想在从 api 返回数据后进行 UI 更新,则需要更改状态,而您无法在constructor
中设置状态。唯一只运行一次并允许您设置状态的地方是componentDidMount()
。
对于事件侦听器,我认为可以将其放入constructor
/componentDidMount
中。但是,官方文档确实建议将其放在componentDidMount()
中。看看这个。
componentDidMount 是在组件挂载后调用的,并且具有 DOM 表示形式。这通常是附加通用 DOM 事件的地方。
通常,构造函数不得有任何副作用。
而且 React 文档也已经提到了这一点:
避免在构造函数中引入任何副作用或订阅。对于这些用例,请改用 componentDidMount((。
>window.addEventListener
在componentDidMount
生命周期中定义,因为在componentDidMount
中定义的代码是在 DOM 渲染后执行的。这将是尝试将任何事件处理程序附加到作为 DOM 一部分的元素的正确时机。
但是如果你在构造函数中这样做,那么在 DOM 完全渲染之前,有很多机会被调用。
在此处阅读更多内容
关于componentDidMount()
的原因有很多
实际上,出于多种原因,componentDidMount
是调用以获取数据的最佳位置。
1-如果要订阅和取消订阅函数,则需要在componentDidMount()
中调用该函数,并在componentWillUnmount()
中取消订阅(在所有操作之后(调用
2-使用didMount可以清楚地表明,在初始渲染之前不会加载数据。这会提醒您正确设置初始状态,这样您就不会最终出现导致错误的未定义状态。
3-componentDidMount()
生命周期方法在render()
后调用,以确保成功加载DOM。
window.addEventListener('resize',this.handleResize(=>您也可以调用构造函数,但稍后如果需要 取消订阅,不能做,因为它是初始阶段(最初称为 仅(。