React Hooks和生命周期的关系
函数组件的本质是函数,没有state的概念的,因此不存在生命周期一说,仅仅是一个render函数而已。但是引入了Hooks之后就变的不同了,它能让组件在不使用class的情况下拥有state,所以就有了生命周期的概念,所谓的生命周期其实就是useState、useEffect和useLayoutEffect。
即:Hooks组件有生命周期,而函数式组件没有生命周期
下面是具体的class与Hooks生命周期对应关系
- constructor:函数式组件不需要构造函数,可以通过调用useState来初始化state。如果计算的代价比较昂贵,也可以传一个函数给useState。
const [num,setNum] = useState(0)
- getDerivedStateFromProps:一般情况下,我们不需要使用它,可以在渲染过程中更新state,以达到实现getDerivedStateFromProps的目的:
function ScrollView({sow}){
const [isScrollingDown,setIsScrollDown] = useState(false);
const [prevRow,setPrevRow] = useState(null);
if(row !== prevRow){
// Row 自上次渲染以来发生过的改变,更新isScrollingDown
setIsScrollingDown(prevRow!==null &&row>prevRow);
setPrevRow(row);
}
return ‘Scrolling down:${isScrollingDown}’;
}
- shouldComponentUpdate:可以用React.memo包裹一个组件来对它的props进行浅比较
const Button = React.memo((props)=>{
// 具体组件
});
React.memo等效于PureComponent,它只是浅比较props。这里也可以使用useMemo优化每一个节点。
4. render:这是函数组件体本身
5.componentDidMount,componentDidUpdate:useLayoutEffect与它们两个的调用阶段是一样的。但是,一般推荐使用useEffect,只有当它出现问题的时候再尝试使用useLayoutEffect。useEffect可以表达这些组合
// componentDidMount
useEffect(() =>{
// 需要在componentDidMount执行的内容
},[])
useEffect(()=>{
// 在componentDidMount,以及count更改时componentDidUpdate执行的内容
document.title = `You clicked ${count} times`;
return ()=>{
// 需要在count更改时componentDidUpdate(先于document.title = ...执行,遵守先清理后更新)
// 以及componentWillUnmount执行的内容
}// 当函数中cleanup函数会按照代码中定义的顺序先后执行,与函数本身的特性无关
},[count]);// 仅在count更改时更新
6.componentWillUnmount:相当于useEffect里面返回的cleanup函数
// componentDidMount/componentWillUnmount
useEffect(()=>{
// 需要componentDidMount执行的内容
return function cleanup(){
// 需要componentWillUnmount执行的内容
}
},[])
- componentDidCatch 和 getDerivedStateFromError:目前还没有这些方法的Hook等价写法
- 对应图示: