React 16.8 引入了 Hooks 的概念,使得函数组件也可以使用 state 和生命周期等特性。与生命周期相关的 Hooks 主要有以下三个:
- useEffect
useEffect 是最常用的一个 Hook,它可以用来替代 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 这三个生命周期函数。useEffect 的作用是在函数组件渲染完成后执行某些操作,例如发送网络请求、操作 DOM 等。
useEffect 接受两个参数:第一个参数是一个回调函数,第二个参数是一个数组,用来指定哪些状态变量发生变化时需要重新执行回调函数。如果不传第二个参数,那么每次渲染都会执行回调函数。
示例代码:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
在这个示例中,useEffect 函数在组件挂载后和每次 count 状态变化时都会调用,用于更新文档标题。
- useLayoutEffect
useLayoutEffect 的作用与 useEffect 类似,但它在所有 DOM 变更之后同步调用回调函数,而不是在浏览器绘制之前调用回调函数。这意味着 useLayoutEffect 可以用来处理需要立即更新 DOM 的情况,例如测量 DOM 元素的大小和位置。
示例代码:
import React, { useState, useLayoutEffect } from 'react';
function Example() {
const [width, setWidth] = useState(window.innerWidth);
useLayoutEffect(() => {
function updateWidth() {
setWidth(window.innerWidth);
}
window.addEventListener('resize', updateWidth);
return () => {
window.removeEventListener('resize', updateWidth);
};
}, []);
return <p>Window width: {width}</p>;
}
在这个示例中,useLayoutEffect 函数在组件挂载后立即调用,用于监听窗口大小变化,并在窗口大小变化时更新状态。
- useMemo
useMemo 是一个用于优化组件性能的 Hook,它可以用来缓存计算结果,避免在每次渲染时都重新计算。useMemo 接受两个参数:第一个参数是一个函数,用来计算结果,第二个参数是一个数组,用来指定哪些状态变量发生变化时需要重新计算结果。
示例代码:
import React, { useState, useMemo } from 'react';
function Example() {
const [count, setCount] = useState(0);
const [factor, setFactor] = useState(1);
const result = useMemo(() => {
return count * factor;
}, [count, factor]);
return (
<div>
<p>Count: {count}</p>
<p>Factor: {factor}</p>
<p>Result: {result}</p>
<button onClick={() => setCount(count + 1)}>Add count</button>
<button onClick={() => setFactor(factor + 1)}>Add factor</button>
</div>
);
}
在这个示例中,useMemo 函数用于缓存 count 和 factor 的乘积,避免在每次渲染时都重新计算。只有当 count 或 factor 发生变化时,才会重新计算结果。
总之,这些与生命周期相关的 Hooks 为函数组件提供了更加灵活和高效的方式来处理状态和生命周期事件。