为什么在React的componentDidMount中订阅了浏览器api事件?

时间:2020-01-10 14:29:26

标签: reactjs browser-api

在本次演讲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中,还有什么优势可以避免吗?还是出于可读性目的而定?

4 个答案:

答案 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之前调用它。

Read more here