# Hooks
# Hooks at a glance
- Hooks don’t work inside classes.
- By default, React runs the effects after every render.
- Rules of Hooks
- Only call Hooks at the top level.
- Only call Hooks from React functions.
# useState
const [state, setState] = useState(initialState);
1
- state is always the newest value.
- setState function identity is stable and will not change on re-renders.
- setState is always replacing the state.
- Functional updates:
setState(preState => preState + 1)
; - initialState is only used on the initial render.
- initialState can be a function:
useState(() => initialState)
# useEffect
useEffect(() => {
// effect
return () => {
// cleanup
};
}, [dependencies]);
1
2
3
4
5
6
2
3
4
5
6
- runs after this render, runs before the next render.
- cleanup
- runs before the component is removed.
- runs before the next effect.
- dependencies fires effect Conditionally.
- run effect once, pass [] to dependencies.
# Recommended
- 只有变化时,需要重新执行 useEffect的变量,才要放到 deps 中。而不是 useEffect 用到的变量都放到 deps 中。
- 在有延迟调用场景时,可以通过 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
2
3
4
5
6
7
8
9
10
11
12
13
14
# useContext
const value = useContext(MyContext);
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
2
3
- memoizedCallback will not change unless a or b changes.
# Recommended
- useCallback 是要和 shouldComponentUpdate/React.memo 配套使用的
- 一般项目中不用考虑性能优化的问题,也就是不要使用 useCallback
# useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
1
- the function passed to useMemo runs during rendering.
- side effects belong in useEffect, not useMemo.
- memoizedValue will be the same for the same inputs.
# Recommended
- 可以适当使用
# useRef
const ref = useRef(initialValue);
1
- useRef will give you the same ref object on every render.
- useRef creates a plain js object.
- ref(mutable) object will persist for the full lifetime of the component.
ref.current = initalValue
;- doesn’t notify us about changes to the current ref value.
# useImperativeHandle
useImperativeHandle(ref, createHandle, [deps])
1
- ref 需要被赋值的ref对象。
- createHandle: createHandle函数的返回值作为ref.current的值。执行时机和useLayoutEffect一致
- [deps] 依赖数组,依赖发生变化会重新执行createHandle函数。