[英]Can I setState inside function passed to useCallback?
This question occurred to me because as we know from the docs:我想到了这个问题,因为正如我们从文档中知道的那样:
useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).
useCallback(fn, deps) 等价于 useMemo(() => fn, deps)。
The docs of useMemo
say: useMemo
的文档说:
Remember that the function passed to useMemo runs during rendering.
请记住,传递给 useMemo 的函数在渲染期间运行。 Don't do anything there that you wouldn't normally do while rendering .
不要在那里做任何你在渲染时通常不会做的事情。 For example, side effects belong in useEffect, not useMemo.
比如副作用属于useEffect,而不是useMemo。
I assume that also implies I can't do setState
.我认为这也意味着我不能做
setState
。
Now, if we have this code:现在,如果我们有这个代码:
const memoizedValue = useMemo(() => computeExpensiveValue(), []);
Does above quote mean we can't do a side effect inside computeExpensiveValue
or the inline function which was the argument to useMemo
?上面的引用是否意味着我们不能在
computeExpensiveValue
或作为useMemo
参数的内联函数中产生useMemo
?
Because if it means we can't do side effect inside computeExpensiveValue
it means we can't do a side effect also in a function passed to useCallback
because that line is same as:因为如果这意味着我们不能在
computeExpensiveValue
产生computeExpensiveValue
则意味着我们也不能在传递给useCallback
的函数中产生useCallback
因为该行与以下内容相同:
const memoizedValue = useCallback(computeExpensiveValue, []);
I see how you got there, but it's a slight misreading of the docs.我明白你是如何到达那里的,但这是对文档的轻微误读。 (Fairly easy mistake to make.)
(相当容易犯的错误。)
The function that the useMemo
docs are talking about isn't your function ( fn
), it's this function in the useCallback
"equivalent useMemo
" example: useMemo
文档所谈论的函数不是您的函数( fn
),而是useCallback
“等效useMemo
”示例中的此函数:
useMemo(() => fn, deps).
// ^^^^^^^^
That function doesn't call any state setters, so it's fine.该函数不调用任何状态设置器,所以没问题。
It's absolutely fine and completely normal to call state setters in callback functions you memoize via useCallack
.在您通过
useCallack
回调函数中调用状态设置器是绝对正常且完全正常的。 (As long as you don't call your callback during rendering.) When you do, be sure to either: (只要您在渲染期间不调用回调。)执行此操作时,请确保:
const fn = useCallback(() => { setSomething(someValueNotFromState); }, []);
or const fn = useCallback(() => { setSomething(something => something + 1); }, []);
or const fn = useCallback(() => { setSomething(something + 1); // I usually avoid this }, [something]); // ^^^^^^^^^
A more verbose example/comparison:一个更详细的例子/比较:
const [value, setValue] = useState(0);
const changeHandler1 = useCallback((event) => {
// Absolutely fine to call `setValue` here
setValue(event.currentTarget.value);
}, []);
// equivalent to:
const changeHandler2 = useMemo(() => {
// NOT okay to call `setValue` here (the function we pass to `useMemo`)
return (event) => {
// Absolutely fine to call `setValue` here
setValue(event.currentTarget.value);
};
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.