在将回调传递给组件时,我应该使用useCallback
钩返回回忆的回调(以防止不需要渲染(:
import doSomething from "./doSomething";
const FrequentlyRerenders = ({ id }) => {
const onEvent = useCallback(() => doSomething(id), [id]);
return (
<ExpensiveComponent onEvent={ onEvent } />
);
};
但是,如果我使用地图怎么办?例如:
import doSomething from "./doSomething";
const FrequentlyRerendersMap = ({ ids }) => {
return ids.map(id => {
const onEvent = useCallback(() => doSomething(id), [id]);
return (
<ExpensiveComponent key={id} onEvent={ onEvent } />
);
});
};
我应该如何正确使用useCallback
?上面是通过多个回调的正确方法吗?它真的有效,并且知道根据数组的项目对每个回调进行纪念?
将返回的映射jsx转换为组件,然后您可以毫无疑问
usecallbackimport doSomething from "./doSomething";
const MappedComponent =(props) => {
const onEvent = useCallback(() => doSomething(props.id), []);
return (
<ExpensiveComponent onEvent={ onEvent } />
);
}
const FrequentlyRerendersMap = ({ ids }) => {
return ids.map(id => {
return <MappedComponent key={id} id={id} />
});
};
现在在文档中明确劝阻这一点。https://reaectjs.org/docs/hooks-rules.html#only-call-hooks-the-the-top-level
旧答案
Re Architect的答案正在避开IMO问题。不过,我认为创建新组件可能是一个好主意。
要回答问题,您的代码:
import doSomething from "./doSomething";
const FrequentlyRerendersMap = ({ ids }) => {
return ids.map(id => {
const onEvent = useCallback(() => doSomething(id), [id]);
return (
<ExpensiveComponent key={id} onEvent={ onEvent } />
);
});
};
实际上是您想在地图中进行回忆的事情。我不知道Uusecallback的实现,但它应该添加很少的内存开销。stackframe,以及他们为将数组减少到回忆功能的某种钥匙中所做的一切。
除非您处理一些具有大量元素的工作,例如反应虚拟化的组件无限滚动,否则您实际上是安全的,对用户返回的方式实际上是安全的。实际上,小型内存开销可能比所有这些组件的租赁者都要便宜得多。