介绍
返回一个函数,函数被调用时强制组件重新渲染。
源码
import { useReducer } from 'react';
const updateReducer = (num: number): number => (num + 1) % 1_000_000;
export default function useUpdate(): () => void {
const [, update] = useReducer(updateReducer, 0);
return update;
}
代码很简单,就是通过改变组件状态来强制组件重新渲染。看似简单但让我产生了一些疑问:
- useUpdate 的使用场景是什么
- 为什么使用 useReducer
- 为什么用
(num+1)%1_000_000的方式来改变 num
思考
useUpdate 的使用场景
useUpdate 用于强制组件渲染一般和 useRef 一起使用。
利用 useRef 处理闭包陷阱
import { useUpdate } from 'react-use';
const Demo = () => {
const countRef = useRef(0);
const update = useUpdate();
const onClick = () => {
setTimeout(() => {
countRef.current++
update()
}, 1_000);
};
return (
<button onClick={onClick}>Clicked: {countRef.current}</button>
);
};
为什么使用 useReduce
基础实现:
export default function useUpdate(): () => void {
const [num, setNum] = useState(0)
return () => {
setNum(num+1)
}
}
用useCallback来返回 函数的记忆化版本,以避免在每次重新渲染组件时都重新生成一个新的函数
export default function useUpdate(): () => void {
const [num, setNum] = useState(0)
return useCallback(() => {
setNum(num+1)
},[])
}
使用 useReduce 来优化,因为useCallback增加了额外的 deps 变化判断,更多的内存分配,并且每次执行 render 都会声明 useCallback 的参数函数这叫 react 内联函数。
import { useReducer } from 'react';
const updateReducer = (num: number): number => (num + 1) % 1_000_000;
export default function useUpdate(): () => void {
const [, update] = useReducer(updateReducer, 0);
return update;
}
为什么用 (num+1)%1_000_000 的方式来改变 num
防止 num 最大值时 num+1 报错