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

Why are browser api event subscribed to in componentDidMount in React?

在这个演讲中 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 部分在 componentDidMount 中?一定要这样吗?

看说话的语气,感觉这种情况挺常见的。

我对反应还很陌生,我也会将浏览器 api 事件订阅也放在构造函数中。

是否有任何优势可以避免为什么将此 window.addEventListener 放在 componentDidMount 中?还是出于可读性的目的?

一般来说,constructors must not have any side effects

还有 React documentation 已经提到过这个:

Avoid introducing any side-effects or subscriptions in the constructor. For those use cases, use componentDidMount() instead.

componentDidMount()

有多种原因

实际上,出于多种原因,componentDidMount 是调用获取数据的最佳位置。

1- 如果您想订阅和取消订阅您的函数,那么您需要在 componentDidMount() 中调用该函数并在 componentWillUnmount()

中调用取消订阅(在所有操作之后)

2-使用 didMount 明确表示在初始渲染之后才会加载数据。这提醒您正确设置初始状态,这样您就不会以导致错误的未定义状态结束。

3-componentDidMount() 生命周期方法在 render() 之后调用以确保 DOM 加载成功。

window.addEventListener('resize',this.handleResize)=> You can call in constructor as well but later if you need to unsubscribe, can't do because it's initial phase(called initially only).

window.addEventListener定义在componentDidMount生命周期中,因为componentDidMount中定义的代码在DOM渲染完成后执行。那将是尝试将任何事件处理程序附加到属于 DOM.

的元素的正确时机

但是如果您在构造函数内部这样做,那么在 DOM 完全呈现之前调用它的机会很多。

Read more here

对我来说很简单。

首先,您只希望 api 调用或事件侦听器 called/initialised 仅一次componentDidMount()constructor每个安装的组件保证 运行 只有一次。

但是,我不会将 api 放入构造函数中,因为如果您希望在从 api 返回数据后进行 UI 更新,you需要状态更改,而您不能在 constructor 中设置状态。唯一只 运行 一次并允许您设置状态的地方是 componentDidMount().

对于Event listeners我觉得可以放在constructor/componentDidMount。但是,官方文档确实建议将其放入 componentDidMount()。看看 this.

componentDidMount is called after the component is mounted and has a DOM representation. This is often a place where you would attach generic DOM events.