首页 > 解决方案 > 反应自定义钩子没有获得新的价值

问题描述

我仍在尝试了解 React Hooks 的工作原理。在构建这个自定义 Hook 时,我注意到一个特殊的行为:

const useCustomHook = () => {
  const [value, setValue] = useState('hello');

  useEffect(() => {
    window.addEventListener('scroll', print, false);
    return () => window.removeEventListener('scroll', print, false);
  }, []);

  const print = () => console.log('print value: ', value); // shows updated value when called directly but original value when scrolling

  return [setValue, print];
};

特殊行为是print输出到控制台的内容。直接调用时print,该值反映了正确的更新值。但是滚动时,print总是将原始值输出到控制台。

示例用法:

应用程序.js

let counter = 0;

const App = () => {
  const [setValue, print] = useCustomHook();

  return (
    <div style={{ margin: '50px auto 10000px' }}>
      <button onClick={() => setValue(counter++)}>Increment</button>{' '}
      <button onClick={print}>Print</button>
    </div>
  );
};

脚步:

  1. 点击Increment
  2. 点击Print-> 控制台:print value: 0
  3. 滚动 -> 控制台:print value: hello

注意是第 3 步,值仍然是hello。滚动时如何获得要打印的正确值?

标签: reactjsreact-hooks

解决方案


您需要从useEffect.

useEffect(() => {
    window.addEventListener('scroll', print, false);
    return () => window.removeEventListener('scroll', print, false);
  }); // remove the empty array

如果将其设置为[],那么它将只执行一次。
如果您删除它,它将在每次更新时执行。

useEffect理想情况下,您希望仅在value更改时重新评估代码。然后,您可以添加print到依赖项数组中。

const useCustomHook = () => {
  const [value, setValue] = useState(-1);

  // useCallback will re-create the function only if 'value' changes
  const print = useCallback(() => {
      console.log('print value: ', value);
  }, [value]);

  // useEffect will be re-evaluated if 'print' changes
  useEffect(() => {
    window.addEventListener('scroll', print, false);
    return () => window.removeEventListener('scroll', print, false);
  }, [print]);

  return [setValue, print];
};

推荐阅读