基础知识 - 生命周期
类的生命周期-更新中
- componentWillUpdate :
即将弃用
数据更新前触发 优先级比较低 会被其它高的优先级覆盖
不推荐
- componentDidUpdate :
数据更新后触发 推荐 有三个形参
老的属性
老的状态,getSnapshotBeforeUpdate周期返回的数据
- shouldComponentUpdate :
性能优化周期函数
控制是否需要组件更新 return true|false true需要 false不需要 有两个参数 新的属性 新的状态
- componentWillReceiveProps :
即将弃用
父组件更新 就会触发子组件这个周期函数 他可以最早拿到父组件传递过来的数据 有一个参数 新的属性
- render :
每次数据更新都会触发render函数
- UNSAFE_ :
可以去除componentWillUpdate 的黄色警告
import React, { Component } from "react";
import ReactDom from 'react-dom';
class Child extends Component {
state = { title: "1-" };
// 父组件传递过来的属性改变 就会触发这个周期 实际上父组件只要更新就会触发
// 这个周期可以可以最早拿到传递过来的数据 可以将传递过来的状态 转换为组件私有
UNSAFE_componentWillReceiveProps(nextProps) {
console.log("-------------componentWillReceiveProps----------");
this.setState({
title: this.state.title + nextProps.title,
});
}
render() {
return <div>{this.state.title}</div>;
}
}
class App extends Component {
state = {
name: "前端猛男",
};
// 更新前 也是不太建议在这里面操作 官方即将弃用
UNSAFE_componentWillUpdate() {
console.log(this.state.name);
console.log("-------------UNSAFE_componentWillUpdate----------");
}
// 更新后 有两个参数 老的属性 老的状态
componentDidUpdate(oldProps, oldState) {
console.log(oldProps, oldState);
console.log(this.state.name);
}
// 是否需要更新 有两个参数 新的属性 新的状态
shouldComponentUpdate(nextProps, nextState) {
// this.state 老的属性
// nextState 新的属性
console.log(nextProps, nextState, "是否需要组件更新周期");
if (this.state.name !== nextState.name) {
return true;
} else {
return false;
}
}
render() {
console.log("render函数");
return (
<div>
<button
onClick={() => {
this.setState({ name: "前端弱男" });
}}
>
点击
</button>
<Child title={this.state.name}></Child>
</div>
);
}
}
ReactDom.render(<App/>,document.getElementById('root'))
shouldComponentUpdate 性能优化案例
只有相等的组件 才会触发更新 其它都被阻止了
import React, { Component } from "react";
import ReactDom from 'react-dom';
class Child extends Component {
// 如果没有性能优化 子组件将会重复渲染多次 造成浪费的内存使用
shouldComponentUpdate(nextProps, nextState) {
// 首次老值 或 新值不同 才会更新渲染 只会触发两次调用
if (
this.props.current === this.props.index ||
nextProps.current === nextProps.index
) {
return true;
}
return false;
}
render() {
console.log("render");
return (
<div
style={{
width: "100px",
height: "100px",
border:
this.props.current === this.props.index
? "1px solid red"
: "1px solid",
float: "left",
margin: 10,
}}
></div>
);
}
}
class App2 extends Component {
state = {
list: [1, 2, 3, 4, 5, 6, 7, 8, 9],
current: 0,
};
render() {
return (
<div>
<input
type="number"
value={this.state.current}
onChange={(Event) => {
this.setState({ current: Number(Event.target.value) });
}}
></input>
<div style={{ overflow: "hidden" }}>
{this.state.list.map((item, index) => (
<Child
key={item}
current={this.state.current}
index={index}
></Child>
))}
</div>
</div>
);
}
}
ReactDom.render(<App2/>,document.getElementById('root'))
执行顺序
render(首次进入) shouldComponentUpdate → componentWillUpdate → render → componentWillReceiveProps → 子render → componentDidMountUpdate
老生命周期的一些问题
- componentWillMount :
在ssr中 这个周期方法会被多次调用 重复触发多遍, 同时在这里如果绑定事件 将无法解绑 导致内存泄露 变得不够安全高效 从而逐步废弃
- componentWillReceiveProps :
外部组件多次 频繁更新传入多次不同的props 会导致不必要的异步请求
- componentWillupdate :
更新前记录Dom状态 可能会做一些处理 与 componentDidUpdate 相隔时间太久 会导致转态不可信