【问题标题】:Unable to get custom hook data from within Debounce无法从 Debounce 中获取自定义挂钩数据
【发布时间】:2021-10-26 08:05:45
【问题描述】:
import { debounce  } from 'lodash';

const App = () => {
  const [text, setText] = useTestState();

  const handleSearchKeyword = (keyword: string) => {
    setText(keyword);
    sendQuery();
  };

  const sendQuery = useCallback(
    debounce(() => {
      console.log(text);
    }, 1000),
    []
  );

  return <input type="text" onChange={handleSearchKeyword} />;
};

const useTestState = () => {
  const [text, setText] = useState('');

  return [text, setText];
};

函数 setData 工作正常

但是,在 sendQuery 函数中会打印 null

我想知道为什么它在 debounce 上不起作用。

【问题讨论】:

    标签: javascript reactjs react-hooks lodash debounce


    【解决方案1】:

    根据您当前的代码sendQuery 将使用相同的文本值,无论您设置多少次,即useCallback 的值被记忆,因为您没有设置任何依赖项。

    您需要像这样将text 作为useCallback 中的依赖项传递。

     const handleSearchKeyword = (keyword: string) => {
        setText(keyword);
        
        debounce(sendQuery, 5000);
      };
    
      const sendQuery = useCallback(
          () => {
              console.log(text);
          },
          [text]
      );
    

    编辑:您可以在 handleSearchKeyword 函数中调用 debounce 或如@Ori Drori 指出的那样,只需将文本作为参数传递给 debounce 函数范围以修复 debounce

    【讨论】:

    • 感谢您的回答。但如果你这样做,我认为去抖不起作用。
    • @jayjay 然后在你打电话给handleSearchKeyword 时设置去抖动sendQuery
    【解决方案2】:

    它不起作用,因为去抖函数是在 text 是空字符串的范围内声明的。由于在text 发生变化时不会重新声明去抖函数,因此它将始终显示原始值。

    您可以在text 更改时重新声明它,但这会增加去抖动,因为它要求功能相同,所以这不起作用

    const sendQuery = useCallback(
      debounce(() => {
        console.log(text);
      }, 1000),
      [text] // creates a new function whenever text changes
    );
    

    这种情况下最简单的解决方案是将keyword作为参数传递给去抖函数:

    const sendQuery = useCallback(
      debounce(text => { // text is a parameter now
        console.log(text);
      }, 1000), []
    );
    
    const handleSearchKeyword = (keyword: string) => {
      setText(keyword);
      sendQuery(keyword); // pass keyword
    };
    

    【讨论】:

    • 感谢您的出色回答,但这是我已经尝试过的。
    • 不是。看看 cmets。
    【解决方案3】:

    这是 React hooks FAQ 中描述的stale props/state problem

    一个不错的解决方案是使用常见问题解答中描述的the "latest state" ref boxing pattern(搜索“最后的手段”):

    import { debounce } from "lodash";
    
    const App = () => {
      const [text, setText] = useState("");
      const latestText = React.useRef();
      React.useEffect(() => {
        latestText.current = text;
      }, [text]);
    
      const handleSearchKeyword = (keyword: string) => {
        setText(keyword);
        sendQuery();
      };
    
      const sendQuery = useCallback(
        debounce(() => {
          console.log(latestText.current);
        }, 1000),
        [],
      );
    
      return <input type="text" onChange={handleSearchKeyword} />;
    };
    

    如果您愿意,可以将其捆绑到自定义挂钩中:

    function useStateWithLatest(initial) {
      const [value, setValue] = useState(initial);
      const latest = React.useRef(initial);
      React.useEffect(() => {
        latest.current = value;
      }, [value]);
      return [value, setValue, latest];
    }
    
    const App = () => {
      const [text, setText, latestText] = useStateWithLatest("");
    
      const handleSearchKeyword = (keyword: string) => {
        setText(keyword);
        sendQuery();
      };
    
      const sendQuery = useCallback(
        debounce(() => {
          console.log(latestText.current);
        }, 1000),
        [],
      );
    
      return <input type="text" onChange={handleSearchKeyword} />;
    };
    

    【讨论】:

      猜你喜欢
      • 2020-06-20
      • 1970-01-01
      • 2023-01-21
      • 1970-01-01
      • 2020-04-21
      • 2021-12-07
      • 2021-02-06
      • 1970-01-01
      • 2021-05-17
      相关资源
      最近更新 更多