【问题标题】:React useCallback hook, not receiving updated dependency state value反应 useCallback 钩子,没有收到更新的依赖状态值
【发布时间】:2021-06-13 22:28:03
【问题描述】:

下面是我试图解决的问题的简化版本。

有人知道为什么我的handleKeydown 方法没有收到更新的activeTab 状态变量吗?我认为因为我添加了activeTab 作为依赖项,所以回调总是会收到更新的值。然而,情况似乎并非如此。

正如预期的那样,每次按下一个键时都会调用回调;但是,activeTab 始终是 null,即初始值。任何帮助表示赞赏!

(我已经包含了一个代码 sn-p 以及一个 jsfiddle 链接(因为 sn-p 似乎由于某种原因没有呈现。jsfiddle 至少呈现 lol)。)

https://jsfiddle.net/Tom904/98veow5b/4/

const Tabs = () => {
  const [activeTab, setActiveTab] = React.useState(null);
  
  
  const handleKeydown = React.useCallback(event => {
    console.log(activeTab);
    // if a user hits the escape key while a tab is active...
    if (event.key === 'Escape' && activeTab) {
      setActiveTab(null);
    }
  }, [activeTab]);

  React.useEffect(() => {
    window.addEventListener('keydown', handleKeydown);
    return () => {
      window.removeEventListener('keydown', handleKeydown);
    };
  }, []);
  
  return (
    <div>
      <button onClick={() => setActiveTab('1')}>
         1
      </button>
      <button onClick={() => setActiveTab('2')}>
         2
      </button>
      <button onClick={() => setActiveTab('3')}>
         3
      </button>
      <div>
        Active tab: {activeTab || 'None'}
      </div>
    </div>
  )
  
}

ReactDOM.render(
  <Tabs/>,
  document.getElementById('root')
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="root"></div>

【问题讨论】:

    标签: javascript reactjs react-hooks dependencies dom-events


    【解决方案1】:

    handleKeydown 函数会随着 activeTab 的每次更改而更新。但是,将函数绑定到keydown 事件的useEffect 仅在挂载时调用。因此,虽然函数被重新创建,但初始值为activeTab 的原始实例被事件处理程序调用。

    这里的useCallback是多余的,你也可以使用useStatefunctional updates形式来避免activeTab的依赖:

    const Tabs = () => {
      const [activeTab, setActiveTab] = React.useState(null);
    
      React.useEffect(() => {
        const handleKeydown = event => {      
          setActiveTab(activeTab => event.key === 'Escape' && activeTab ? null : activeTab);
        };
      
        window.addEventListener('keydown', handleKeydown);
        return () => {
          window.removeEventListener('keydown', handleKeydown);
        };
      }, []);
      
      return (
        <div>
          <button onClick={() => setActiveTab('1')}>
             1
          </button>
          <button onClick={() => setActiveTab('2')}>
             2
          </button>
          <button onClick={() => setActiveTab('3')}>
             3
          </button>
          <div>
            Active tab: {activeTab || 'None'}
          </div>
        </div>
      )
      
    }
    
    ReactDOM.render(
      <Tabs/>,
      document.getElementById('root')
    );
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    
    <div id="root"></div>

    【讨论】:

    • 谢谢,没有遇到同样的问题,我非常了解我的生命周期,但这个问题(和答案)帮助我发现了代码中的错误:D
    猜你喜欢
    • 1970-01-01
    • 2021-04-23
    • 2022-01-16
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2020-11-02
    • 2020-03-09
    • 2021-04-17
    相关资源
    最近更新 更多