React.useCallback 是否会记住柯里化函数?

Ram*_*ddy 5 javascript memoization reactjs

有时我会在 内部声明柯里化函数时使用这种模式useCallback

const Child = ({ handleClick }) => {
  return (
    <>
      <button onClick={handleClick("foo")}>foo</button>
      <button onClick={handleClick("lorem")}>lorem</button>
    </>
  );
};

export default function App() {
  const [state, setState] = useState("");

  const handleClick = useCallback(
    (newState) => () => {
      setState(newState);
    },
    []
  );

  return (
    <div className="App">
      <Child handleClick={handleClick} />
      <p>{state}</p>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

编辑 serene-platform-kuzc2

因为我想将参数从 JSX 传递到事件处理程序并避免多个处理程序。

当组件重新渲染时,handleClick将被调用,返回的函数将被分配给 prop onClick,但它每次都是一个新函数还是嵌套函数也会被 记忆useCallback

PS:这是一个简单的例子。假设useCallback具有多个依赖项的用法

You*_*saf 4

编辑

以下答案是指OP 代码的初始版本handleClick,其中未作为 props 传递给Child组件。


在这种情况下你真的不需要useCallback

实际上,在这种情况下最好不要使用钩子,useCallback因为:

  1. useCallback每次组件重新渲染时都会创建传递给的回调函数。结果,无论如何都会创建一个新函数,就像不使用useCallback

  2. 对于您的情况,获取该函数的记忆版本handleClick不会带来任何好处。handleClick如果将其作为 prop 传递给子组件,则记忆将非常有用。

...但是它每次都是一个新函数还是嵌套函数也会被 useCallback 记住?

不,嵌套函数不会被记忆。

handleClick是一个记忆函数,但该记忆函数每次执行时都会返回一个新函数。

调用handleClick就像调用任何其他函数一样 - 每次调用它时都会创建在其体内声明的任何内容。

  • _每次组件重新渲染时都会创建传递给 useCallback 的函数_。为什么,一个空数组作为钩子中的第二个参数传递。 (3认同)
  • @RohitSharma 空依赖数组不会阻止对回调函数进行求值。创建了一个新函数,但“useCallback”将丢弃它并返回一个记忆函数。`useCallback(() =&gt; {}, [])` 的计算就像任何其他函数调用表达式一样。每次调用“useCallback”时都会创建匿名回调函数。 (2认同)