# 如果避免声明周期中的坑
- 不在恰当的时候调用了不该调用的代码
- 需要调用时,不要忘记调用
主要有下面几种容易造成声明周期的坑
- getDerivedStateFromProps 容易编写反模式代码,使受控组件与非受控组件区分模糊
- 不要使用已经标记弃用的生命周期函数。容易导致问题。
- shouldComponentUpdate 通过返回 true 或者 false 来确定是否需要出发新的渲染,主要用于性能优化。
- 如果在 componentWillUnmount 函数中忘记解除事件绑定,取消定时器等清理操作,容易引发 bug。
- componentWillUpdate 同样是由于新的异步渲染机制,而被标记废弃,不推荐使用,原先的逻辑可结合 getSnapshotBeforeUpdate 与 componentDidUpdate 改造使用。
- 如果没有添加错误边界处理,当渲染发生异常时,用户将会看到一个无法操作的白屏,所有要添加错误处理。
# 什么情况下会触发重新渲染
函数组件 函数组件任何情况下都会重新渲染。它并没有生命周期,可以使用 React.memo优化。React.memo 并不是阻断渲染,而是跳过渲染组件的操作直接复用最近一次渲染的结果,这点与 shouldComponentUpdate 完全不同。
React.Component 如果不实现 shouldComponentUpdate 函数,则有两种情况下会触发重新渲染。
- 当 state 发生变化时。
- 当父组件的 props 传入时。无论 Props 有没有变化,只要传入就会引发重新渲染。
React.PureComponent PureComponent 默认实现了 shouldComponentUpdate 函数,所以仅在props 与 state 进行浅比较后,确认有变更才会触发重新渲染。
# 错误边界
但渲染时的报错,只能通过 componentDidCatch 捕获。这是在做线上页面报错监控时,极其容易忽略的点儿。
# React 请求应该放在哪里,为什么?
对于异步请求,应该放在 componentDidMount 中去操作。从时间顺序来看,除了 componentDidMount 还可以有以下选择:
- constructor:可以放,但从设计上而言不推荐。constructor 主要用于初始化 state 与函数绑定,并不承载业务逻辑。而且随着类属性的流行,constructor 已经很少使用了。
- componentWillMount:已被标记废弃,在新的异步渲染架构下会触发多次渲染,容易引发 Bug,不利于未来 React 升级后的代码维护。 所以请求都放在 componentDidMount 中。