React16.3.0以后的生命周期(二) – 更新、卸载、异常

组件更新

static getDerivedStateFromProps()
当本地state需要根据props来改变的时候可调用此方法。
这个方法是在render()前会被执行,只要执行render()都会被在之前被触发。
该方法有两个参数props和state; 返回值为state对象, 不需要返回整体state,把需要改变的state返回即可。
示例:
static getDerivedStateFromProps(props, state) {
if(props.color !== state.color) {
return {color: props.color};
}
}

shouldComponentUpdate()
此方法有两个参数:shouldComponentUpdate(nextProps, nextState).
返回值为true或者false, 默认返回true.
主要使用它来控制组件要不要渲然,常用作性能优化。
触发此方法的条件是:组件接收任意props或者state时都会被调用。需要注意的是在第一次render()时和在调用forceUpdate()时都不会被触发。
示例:
shouldComponentUpdate(nextProps, nextState) {
if(nextProps.color !== this.props.color || nextState.size !== this.state.size) {
return true;
}
return false;
}

render()
这个方法是React组件中必须要提供的方法。当state或者props任一数据有更新时都会执行。
需要注意当继承PureComponent时,不会对对象进行深度比较,也就是,不会根据对象内的对象变化时执行render().
render()是一个纯函数,也就是不能在这个方法中有类似setState()这样的行为。
返回的数据类型可以有:

null、String、Number、Array、Boolean。
React elements
Fragment

Portal
注意:不能返回undefined.

当shouldComponentUpdate()返回false时,无论state和props有没有变化,这个方法都不执行。
示例:
render() {
return (
<div>{this.state.color}</div>
);
}

getSnapshotBeforeUpdate()
getSnapshotBeforeUpdate(prevProps, prevState)在render将组件渲然到dom中就会执行。
如果不实现该方法则返回null.
返回的数据由自己定义,并且返回的数据作为componentDidUpdate方法中的参数。
示例:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}

getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight – list.scrollTop;
}
return null;
}

render() {
return (
<div ref={this.listRef}>{/* …contents… */}</div>
);
}
}

componentDidUpdate()
该方法在组件更新后立即执行,并且在组件挂载阶段不执行。
componentDidUpdate(prevProps, prevState, snapshot)第三个参数就是上节中提到的。
示例:
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight – snapshot;
}
}

组件卸载

componentWillUnmount()
在组件被卸载或者销毁的时候执行,方法中不能再有setState的动作。
一般用作清除组件中起的定义器、webSocket等。
示例:
componentWillUnmount() {
if(this.timer) {
window.clearInterval(this.timer);
this.timer = null;
}
}
在线示例

组件异常处理

componentDidCatch()
componentDidCatch(error, info) 异常的处理。
只能捕获组件树的异常,无法捕获这个方法内的异常。
示例:
定义一下异常处理组件:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}

componentDidCatch(error, info) {
this.setState({ hasError: true });
window.console.log(error, info);
}

render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
使用这个异常组件:
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>

推荐阅读《React 手稿》

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理