react生命周期
渲染流程
Reconcile计算状态变化包含diff. render阶段 可中断
Render渲染状态变化 reactDom reactNative。 commit阶段
this.setState=>reconcile去计算状态变化=>reactDom渲染在视图中
新版生命周期
Mount | Update | Unmount | Error | |
---|---|---|---|---|
Render阶段 | constructor | |||
Render阶段 | getDerivedStateFromProps | getDerivedStateFromProps | getDerivedStateFromError | |
Render阶段 | shouldComponentUpdate | |||
Render阶段 | render | render | ||
pre-commit阶段 | getSnapshotBeforeUpdate | |||
commit阶段 | componentDidMount | componentDidUpdate | componentWillUnmount | componentDidCatch |
commit阶段 |
组件树
挂载
- ReactDom.render
- 进入render阶段,深度优先遍历创建Fiber树
- 进入commit阶段,从子节点开始执行生命周期函数
更新
每次setState都会完整创建Fiber树
双缓存树
hooks模拟class生命周期
class 组件 | Hooks 组件 |
---|---|
constructor | useState |
getDerivedStateFromProps | useEffect 手动对比 props, 配合 useState 里面 update 函数 |
shouldComponentUpdate | React.memo |
render | 函数本身 |
componentDidMount | useEffect 第二个参数为[] |
componentDidUpdate | useEffect 配合useRef |
componentWillUnmount | useEffect 里面返回的函数 |
componentDidCatch | 无 |
getDerivedStateFromError | 无 |
import React, { useState, useEffect, useRef, memo } from 'react';
// 使用 React.memo 实现类似 shouldComponentUpdate 的优化, React.memo 只对 props 进行浅比较
const UseEffectExample = memo((props) => {
console.log("===== UseStateExample render=======");
// 声明一个叫 “count” 的 state 变量。
const [count, setCount] = useState(0);
const [count2, setCount2] = useState(0);
const [fatherCount, setFatherCount] = useState(props.fatherCount)
console.log(props);
// 模拟 getDerivedStateFromProps
useEffect(() => {
// props.fatherCount 有更新,才执行对应的修改,没有更新执行另外的逻辑
if(props.fatherCount == fatherCount ){
console.log("======= 模拟 getDerivedStateFromProps=======");
console.log(props.fatherCount, fatherCount);
}else{
setFatherCount(props.fatherCount);
console.log(props.fatherCount, fatherCount);
}
})
// 模拟DidMount
useEffect(() => {
console.log("=======只渲染一次(相当于DidMount)=======");
console.log(count);
}, [])
// 模拟DidUpdate
const mounted = useRef();
useEffect(() => {
console.log(mounted);
if (!mounted.current) {
mounted.current = true;
} else {
console.log("======count 改变时才执行(相当于DidUpdate)=========");
console.log(count);
}
}, [count])
// 模拟 Didmount和DidUpdate 、 unmount
useEffect(() => {
// 在 componentDidMount,以及 count 更改时 componentDidUpdate 执行的内容
console.log("======初始化、或者 count 改变时才执行(相当于Didmount和DidUpdate)=========");
console.log(count);
return () => {
console.log("====unmount=======");
console.log(count);
}
}, [count])
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
<button onClick={() => setCount2(count2 + 1)}>
Click me2
</button>
</div>
);
});