useCallback
正如您正确暗示的那样,目的是记住:
useCallback(fn, deps) 等价于 useMemo(() => fn, deps)。
至于用于什么useMemo
:
您可以依赖 useMemo 作为性能优化,而不是语义保证。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
但作为一项规则,useState
在渲染之间是稳定的(即预先记忆),所以你不需要再次记忆它。
那么问题来了,您的“做某事”是否低于昂贵的计算?使用 应该不会很麻烦useCallback
,但它很可能是您不需要的样板代码,并且几乎可以直接使用您的setActive
函数。
const [active, setActive] = useState(false);
const onActiveChanged = useCallback(
isActive => () => {
// do something
setActive(isActive);
},
[setActive], // or just [] is okay?
);
在 useCallback 和其他钩子中防止不必要的依赖的另一种方法是使用功能更新。结果是你可以拥有这些:
const [active, setActive] = useState(false);
const [expensiveCalc, setExpensiveCalc] = useState(false);
const onExpensiveCalc = useCallback(
expensiveInput => () => {
const newState = doExpensiveCalc(expensiveInput);
expensiveCalc(newState);
},
[setActive], // here for completeness
);
return (<>
// expensive calculation
<button onClick={onExpensiveCalc}>Do lengthy calculation</button>
// cheap calculation, using functional updates
<button onClick={() => setActive(prevBoolean => !prevBoolean)}>Cheap Set Active</button>
</>)
请注意,在 onClick 中设置状态的工作方式有一些细微差别,您应该使用箭头函数,因此您setActive
在单击时运行,而不是渲染。这显示在上面的第二个答案中,但没有解释。
另请参阅:React 中的 useState() 是什么?