如果有功能组件,我现在应该使用react钩子吗?如果用useCallback包装用props传递的每个函数,用useMemo包装其他props值?
我的组件中还具有依赖于任何props值的自定义功能,我应该用useCallback包装它吗?
有什么好的方法来决定使用此钩子从组件中包装哪些prop或const值?
如果这可以提高性能,为什么不一直这样做呢?
让我们考虑在包装点击处理程序并添加自定义逻辑的自定义按钮
function ExampleCustomButton({ onClick }) {
const handleClick = useCallback(
(event) => {
if (typeof onClick === 'function') {
onClick(event);
}
// do custom stuff
},
[onClick]
);
return <Button onClick={handleClick} />;
}
让我们考虑自定义按钮,我们在其中包装点击处理程序并根据情况添加自定义逻辑
function ExampleCustomButton({ someBool }) {
const handleClick = useCallback(
(event) => {
if (someBool) {
// do custom stuff
}
},
[someBool]
);
return <Button onClick={handleClick} />;
}
在这两种情况下,我应该用useCallback包装处理程序吗?
与使用备忘录类似的案例。
function ExampleCustomButton({ someBool }) {
const memoizedSomeBool = useMemo(() => someBool, [someBool])
const handleClick = useCallback(
(event) => {
if (memoizedSomeBool) {
// do custom stuff
}
},
[memoizedSomeBool]
);
return <Button onClick={handleClick} />;
}
在此示例中,我甚至将备注值传递给useCallback。
另一种情况,如果在组件树中许多组件记忆相同的值呢?这对性能有何影响?
答案 0 :(得分:5)
不值得,有多种原因:
将所有钩子放在一起-键入所有的钩子比在用户将钩子放到应用程序中所花费的时间要多得多。遵循良好的旧规则:先测量,然后优化。
答案 1 :(得分:2)
我同意@jalooc提出的原则
要提供有关OP中展示的用例的更多信息,这是我的建议:
function Component() {
const callback = useCallback(() => { dostuff }, [deps])
return <Child prop={callback} />
}
如果Child
是要渲染的非常昂贵的组件,则上述内容有意义。因此,它可能是这样导出的:
function Child() {
...this takes significant CPU...
}
// Export as a pure component
export default React.memo(Child)
function Component({ foo }) {
// This very expensive computation will only run when it's input (foo)
// changes, allowing Component to re-render without performance issues
const bar = useMemo(() => {
... something very complicated with `foo` ...
}, [foo])
return <div>{bar}</div>
}
useCallback
)或将其移出范围。React.memo
使用#2
使其纯净useMemo
)