跳到主要内容

hooks

useState

const [state, setState] = useState(initialState);

最常用的 hook ,但是有两个注意点

  1. 如果你向 initialState 传递一个函数,它会被视作是初始化函数,react 会调用这个函数,并且将这个函数的返回值作为初始状态。初始函数应当是一个纯函数(它应当没有任何参数,而且应当幂等),这是为了保证你的不会制造出 accidential impurities
  2. react 会在严格模式下将这个 Initializer 调用两次。
  3. setState 可以接收一个函数,如果 setState 的入参不是一个函数,它在 React 18 下可能会被批量执行

useEffect

useEffect(setup, dependencies?)

第二常用的 hook,用于在 「自变量发生变化」后触发副作用。 useEffect 常用于组件首次挂载时需要发请求。(此时,Dependencies 为空数组) 在 setup 中可以返回一个函数,称之为 cleanup 函数。react 会在组件从 DOM 中 removed 之后调用 cleanup 函数。

在父子组件中,子组件的 useEffect 先触发,父组件的 useEffect 后触发。

useRef

const ref = useRef(initialValue);

useRef 常用于操作 DOM

image.png

也可以用于在重渲染之间保存状态(useState 是 useRef 的语法糖)

function App() {
const [foo, setFoo] = useState();
const isInitial = useRef(true);
useEffect(() => {
if (isInitial.current) {
isInitial.current = false;
return;
}
// 首次加载不触发,当 foo 发生变化再触发
doSomething();
}, [foo]);
}

useContext

const value = useContext(SomeContext);

image.png

useContext 是 context comsumer 的简写,同时,可以将其进一步简化,从而得到 useMode 之类的自定义 hook 。

在实际的项目中,我总结的最佳实践是:

  1. 搭配自定义 hook 使用,这样子组件只需要 useXXContext() 即可。
  2. 搭配 react-error-bounrdary 设置错误边界,这样会有更加清晰的错误提示。

预览链接

useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init?)

image.png

useMemo

useMemo 用于在重渲染之间保存计算结果,这个计算结果(calculateValue)通常是耗时的计算函数。(如下图,calculateValue 的返回值,才是实际要 memorized 的值,也就是 cachedValue)

const cachedValue = useMemo(calculateValue, dependencies);

image.png

注意和 memo 区分

const MemoizedComponent = memo(SomeComponent, arePropsEqual?)

memo 的实际使用场景是:当父组件自身的 state 发生变化,此时父组件会发生重渲染,父组件的重渲染会带动子组价发生重渲染。如果我们并不希望此时子组件发生重渲染,那么可以使用 memo 包裹一下子组件。

image.png

useCallback

useCallback 用于在重渲染之间缓存函数定义

const cachedFn = useCallback(fn, dependencies);

有关 useMemo useCallback 和 memo 之间的正确使用姿势,我学习了这篇文章 useCallback 是 useMemo 的语法糖。

const foo = useMemo(() => () => doSomething(), [deps]);
// 等价于
const foo = useCallback(() => doSomething(), [deps]);

useImperativeHandler

用来定制传入 ref 的行为,最常见的例子是,点击编辑的时候,输入框获得焦点(focused)。

image.png

useLayoutEffect

在每次浏览器重绘之前触发的 hook ,对于性能有伤害。

典型的例子是:实现当 tooltip 不能在上方被放下时,放到下面。 image.png

而且尽量使用 useEffect 代替

useDebugValue

用于在 react devtool 上展示信息,没怎么用过暂不展开