我正在尝试制作一个简单的示例,该示例遵循文档https://reactjs.org/docs/hooks-reference.html#usecallback中的React Hooks示例
在没有useCallback
的情况下,代码可以按以下示例进行查找:
import React, { useCallback } from "react";
function Test(props) {
function doSomething(a, b) {
console.log("doSomething called");
return a + b;
}
return (
<div>
{Array.from({ length: 3 }).map(() => (
<div>{doSomething('aaa','bbb')}</div>
))}
</div>
);
}
export default Test;
但是,当我如下添加我认为适用于useCallback
的代码时,出现错误(未定义a)
import React, { useCallback } from "react";
function Test(props) {
function doSomething(a, b) {
console.log("doSomething called");
return a + b;
}
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b]
);
return (
<div>
{Array.from({ length: 3 }).map(() => (
<div>{memoizedCallback("aaa", "bbb")}</div>
))}
</div>
);
}
export default Test;
问题代码在这里:
答案 0 :(得分:2)
useCallback
的目的是能够利用当前范围内的道具或状态,并且在重新渲染时可能会改变。然后,依赖项数组会告诉React当您需要新版本的回调时。如果您想记住昂贵的计算,则需要使用useMemo
。
下面的示例演示useCallback
和useMemo
之间的区别以及不使用它们的后果。在此示例中,我使用React.memo
来阻止Child
重新呈现,除非其属性或状态发生变化。这样可以看到useCallback
的好处。现在,如果Child
收到新的onClick
道具,它将导致重新渲染。
子级1正在接收未存储的onClick
回调,因此,每当父组件重新渲染时,子级1始终会收到一个新的onClick
函数,因此必须重新渲染。
子级2使用从onClick
返回的已记忆的useCallback
回调,子级3通过useMemo
使用等效的回调来演示
useCallback(fn,输入)等同于useMemo(()=> fn,输入)
对于子项2和3,每次单击子项2或3时,回调仍将执行,useCallback
仅确保在没有依赖项时传递相同版本的onClick
函数改变了。
显示器的以下部分有助于指出正在发生的事情:
nonMemoizedCallback === memoizedCallback:false | true
我分别显示somethingExpensiveBasedOnA
和使用useMemo
的备忘录版本。出于演示目的,我使用了不正确的依赖项数组(我故意省略了b
),以便您可以看到,当b
更改时,备注版本不会更改,但是当{{ 1}}的更改。每当a
或a
更改时,非存储版本都会更改。
b
答案 1 :(得分:0)
在{ }
之后有额外的=>
,因此创建了一个块和作用域,只需将它们和;
都删除即可,因为它使它成为一条语句。否则,将参数传递给它,使用此
const memoizedCallback = useCallback(
() => doSomething(a, b)
,
[a, b]
);
之所以说undefined
是因为=> { }
的范围未收到a,b
。希望对您有所帮助。