# Hooks

# Hooks at a glance

  1. Hooks don’t work inside classes.
  2. By default, React runs the effects after every render.
  3. Rules of Hooks
    1. Only call Hooks at the top level.
    2. Only call Hooks from React functions.

# useState

const [state, setState] = useState(initialState);
1
  1. state is always the newest value.
  2. setState function identity is stable and will not change on re-renders.
  3. setState is always replacing the state.
  4. Functional updates: setState(preState => preState + 1);
  5. initialState is only used on the initial render.
  6. initialState can be a function: useState(() => initialState)

# useEffect

useEffect(() => {
  // effect
  return () => {
    // cleanup
  };
}, [dependencies]);
1
2
3
4
5
6
  1. runs after this render, runs before the next render.
  2. cleanup
    • runs before the component is removed.
    • runs before the next effect.
  3. dependencies fires effect Conditionally.
  4. run effect once, pass [] to dependencies.
  1. 只有变化时,需要重新执行 useEffect的变量,才要放到 deps 中。而不是 useEffect 用到的变量都放到 deps 中。
  2. 在有延迟调用场景时,可以通过 ref 来解决闭包问题。
const [count, setCount] = useState(0);

// 通过 ref 来记忆最新的 count
const countRef = useRef(count);
countRef.current = count;

useEffect(() => {
  const timer = setTimeout(() => {
    console.log(countRef.current);
  }, 3000);
  return () => {
    clearTimeout(timer);
  };
}, []);
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# useContext

const value = useContext(MyContext);
1
  1. A component calling useContext will always re-render when the context value changes.

# useCallback

const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);
1
2
3
  1. memoizedCallback will not change unless a or b changes.
  1. useCallback 是要和 shouldComponentUpdate/React.memo 配套使用的
  2. 一般项目中不用考虑性能优化的问题,也就是不要使用 useCallback

# useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
1
  1. the function passed to useMemo runs during rendering.
  2. side effects belong in useEffect, not useMemo.
  3. memoizedValue will be the same for the same inputs.
  1. 可以适当使用

# useRef

const ref = useRef(initialValue);
1
  1. useRef will give you the same ref object on every render.
  2. useRef creates a plain js object.
  3. ref(mutable) object will persist for the full lifetime of the component.
  4. ref.current = initalValue;
  5. doesn’t notify us about changes to the current ref value.

# useImperativeHandle

useImperativeHandle(ref, createHandle, [deps])
1
  1. ref 需要被赋值的ref对象。
  2. createHandle: createHandle函数的返回值作为ref.current的值。执行时机和useLayoutEffect一致
  3. [deps] 依赖数组,依赖发生变化会重新执行createHandle函数。

# Questions

Last Updated: 2/8/2023, 2:30:06 AM