当 props 只包含 onChange 而没有其他元素时,在这种情况下 useCallback 是否不必要,因为整个组件已经基于 onChange 进行了备忘录?
它是基于所有道具记忆的,而不仅仅是onChange。是的,useCallback 在那里是不必要的。
如果我们添加一个额外的属性(比如value 用于<input> 的初始值),那么我认为useCallback 会变得有用,否则即使onChange 没有,handleChange 也会被重新创建t 改变,但价值改变。对吗?
如果您想在更新input 时更新value 而不是更新onChange,您可以将value 添加到您的props 并继续为您的handleChange 使用useCallback(如果您喜欢,因此 React 在设置值时不必换入新的事件处理程序;我的印象是这通常是矫枉过正的)。例如:
const UserInput = React.memo(({ onChange, value }: UserInputProps) => {
const handleChange = useCallback(
(event) => {
onChange(event.target.value);
},
[onChange]
);
return <input type="text" value={value} onChange={handleChange} />;
});
如果 onChange 属性没有改变,这将使用最新的 value 并重用以前的 handleChange。
在这种情况下,您可能不会保留React.memo,如果您预计value 会因onChange 而发生变化。也就是说,如果您希望 value 在每次调用组件时都不同,那么 React.memo 对 props 的检查是您可能不需要做的额外工作:
const UserInput = ({ onChange, value }: UserInputProps) => {
const handleChange = useCallback(
(event) => {
onChange(event.target.value);
},
[onChange]
);
return <input type="text" value={value} onChange={handleChange} />;
};
但如果您希望 React.memo 继续检查 props 并且在 props 均未更改时不调用您的函数,则可以保留它。
如果你只是想为你的组件提供 initial 值然后在本地控制它,你可以继续使用React.memo(因为它仍然呈现相同的相同的输入道具),在这种情况下你不需要useCallback:
const UserInput = React.memo(({ onChange, initialValue }: UserInputProps) => {
const [value, setValue] = useState(initialValue);
const handleChange = (event) => {
setValue(event.target.value);
onChange(event.target.value);
};
return <input type="text" value={value} onChange={handleChange} />;
});
只有在 onChange 或 initialValue 发生变化时才会调用它。您还可以在那里使用useCallback,以便再次仅在input 上更新onChange onChange 属性更改,以避免React 删除旧处理程序并在只有@ 时设置新处理程序987654357@变化:
const UserInput = React.memo(({ onChange, initialValue }: UserInputProps) => {
const [value, setValue] = useState(initialValue);
const handleChange = useCallback(
(event) => {
setValue(event.target.value);
onChange(event.target.value);
},
[onChange]
);
return <input type="text" value={value} onChange={handleChange} />;
});
旁注:要记住的一件事是,每次调用组件函数时都会创建一个新的handleChange 函数,即使您使用的是useCallback。它必须是,所以它可以作为参数传递给useCallback。唯一的区别是您是使用那个新函数,还是第一次创建的原始函数(useCallback 的结果)。我认为重用为给定的一组依赖项创建的第一个依赖项的原因是尽量减少传递给子组件的更改。