Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
Hook使用规则
- 只在最顶层使用
Hook- 不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。
- 只在
React函数中使用Hook- 在 React 的函数组件中调用 Hook
- 在自定义 Hook 中调用其他 Hook
常用Hook API
useState
useState 会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数,更新函数类似 class 组件的 setState 。useState 唯一的参数就是初始 state。
Effect Hook
useEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力。它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。
可以返回一个函数,作为清除操作,在调用 componentWillUnmount 的时机执行。
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
useEffect 支持传入第二个参数,当第二个参数值更改时,才进行更新。
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新
useCallback
把内联回调函数及依赖项数组作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。
// 当下述方法中的a,b 发生改变时,才会执行
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)。
useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
跟 useCallback 一样,会缓存入参,只有当入参发生变化,才会执行计算的函数,避免每次渲染时都进行计算。
副作用不要用 useMemo ,要用 useEffect 。传入 useMemo 的函数会在渲染期间执行。
如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值。