在本次演讲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)
}
}
为什么componentDidMount中的window.addEventListener
部分?一定要吗?
从谈话的语气中,我觉得这种情况很普遍。
我还很陌生,所以我也会将浏览器api事件订阅也放入构造函数中。
关于为什么将这个window.addEventListener
放在componentDidMount中,还有什么优势可以避免吗?还是出于可读性目的而定?
答案 0 :(得分:1)
通常为constructors must not have any side effects。
React documentation也已经提到了这一点:
避免在构造函数中引入任何副作用或订阅。对于这些用例,请改用componentDidMount()。
答案 1 :(得分:1)
对我来说很简单。
首先,您只希望api调用或事件侦听器仅被调用/初始化一次 ,保证每个已安装的组件componentDidMount()
和constructor
仅运行一次。
但是,我不会将api放在构造函数中,因为如果您希望在从api返回数据后要更新UI,则y 您需要状态更改,而您无法在constructor
中设置状态。只能运行一次并允许您设置状态的唯一地方是componentDidMount()
。
对于事件侦听器,我认为可以将其放在constructor
/ componentDidMount
中。但是,官方文档确实建议将其放在componentDidMount()
中。看看this。
componentDidMount在组件安装后调用,并具有DOM表示形式。通常在这里可以附加一般的DOM事件。
答案 2 :(得分:0)
componentDidMount()
实际上,出于多种原因,componentDidMount
是发出调用以获取数据的最佳位置。
1-如果要订阅和取消订阅函数,则需要在componentDidMount()
中调用该函数,然后在componentWillUnmount()
中取消订阅(所有操作之后)
2-使用didMount可以清楚地说明,只有在初始渲染之后才会加载数据。这可以提醒您正确设置初始状态,以免最终导致出现错误的未定义状态。
在componentDidMount()
之后调用 3-render()
生命周期方法,以确保成功加载DOM。
window.addEventListener('resize',this.handleResize) => 您也可以调用构造函数,但稍后需要 取消订阅,无法执行,因为它处于初始阶段(最初称为 仅)。
答案 3 :(得分:0)
在window.addEventListener
生命周期中定义componentDidMount
,因为在DOM呈现之后,将执行componentDidMount
中定义的代码。正是时候尝试将任何事件处理程序附加到DOM的元素上。
但是,如果您在构造函数中这样做,则有很多机会在完全呈现DOM之前调用它。