如何使 lodash debounce 与 React 中 useCallback 的多个依赖项一起工作

How to make lodash debounce work with multiple dependencies of useCallback in React

我正在使用 lodash 和 useCallback 来创建一个可记忆的,以便更多地了解回调的真正工作原理但卡住了。这是我的代码的简单示例

import { useCallback, useEffect, useState } from "react";
import "./styles.css";
import { debounce } from "lodash";

const Test = ({ name }) => {
  const [testName, setTestName] = useState("");
  const changeName = () => {
    setTestName((Math.random() + 1).toString(36).substring(7));
  };

  const debounceChangeTestName = useCallback(
    debounce(() => console.log(testName), 2000),
    // 1
    [testName]
  );

  useEffect(() => {
    debounceChangeTestName(testName);
  }, [testName, debounceChangeTestName]);

  useEffect(() => {
    setTestName(name);
  }, [name]);

  return (
    <div>
      {testName} <br />
      <input type="button" onClick={changeName} value="Change" />
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <Test name="for test" />
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

谁能给我解释一下2个问题

  1. 如果我不添加对 debounce 函数的依赖(我注释 1 的地方),为什么我不能记录 testName 的值?它在下面的useEffect中没有改变吗?
  2. 如果我向 debounce 函数添加依赖项,我如何才能只记录 testName 的最后结果(在上面的代码中,它会记录所有 testName 值,直到我停止单击)

在您执行 useCallback 的那一刻,只要依赖项相同,该函数就会被记住。如果您在函数内部硬编码一个变量,则执行的函数将始终具有相同的结果。 虽然在依赖数组中使用 testMessage 可以解决问题,但它并不会真正导致任何反跳。由于每次依赖项更改时都会重新创建 debounce,因此您总是会得到一个不会“记住”上一次调用的新实例。

只需将您的 testName 作为参数传递,而不是依赖状态中的值:

  const debounceChangeTestName = useCallback(
    debounce(msg => console.log(msg), 2000),
    [],
  )

这是否回答了您的问题?