javascript - 在事件监听器函数中无法访问 React hooks 值

标签 javascript reactjs addeventlistener react-hooks

我决定使用 windom 宽度和调整大小事件监听器为我的组件使用 React Hook 。问题是我无法访问我需要的当前值。我得到了在添加事件监听器时设置的嵌套值。

将函数传递给值 setter 函数对我来说不是解决方案,因为它会强制渲染并破坏我的其他功能。

我附上一个简单的例子来说明核心问题:

import React, { Component, useState, useEffect } from 'react';
import { render } from 'react-dom';

const App = () => {
  const [width, setWidth] = useState(0);

  const resize = () => {
    console.log("width:", width); // it's always 0 even after many updates
    setWidth(window.innerWidth);
  };

  useEffect(() => {
    resize();
    window.addEventListener("resize", resize);
    return () => window.removeEventListener("resize", resize);
  }, []);

  return <div>{width}</div>;
}

render(<App />, document.getElementById('root'));

LIVE DEMO IS HERE

求助。

最佳答案

每次渲染你都会得到一份新的 resize 函数。每个副本都捕获 width 的当前值。您的监听器有一个副本,该副本是在第一次渲染时使用 width = 0 创建的。

要解决此问题,您有多种选择:

  1. width 改变时更新监听器

    useEffect(() => {
      resize();
      window.addEventListener("resize", resize);
      return () => window.removeEventListener("resize", resize);
    }, [width]);
    
  2. 使用 functional updates获取监听器中的当前宽度

    const resize = () => {
      setWidth(oldWidth => {
        console.log("width:", oldWidth);
        return window.innerWidth
      });
    };
    
  3. 将宽度存储在 mutable reference

    const widthRef = useRef(width);
    
    const resize = () => {
      console.log("width:", widthRef.current);
      widthRef.current = window.innerWidth;
      setWidth(window.innerWidth);
    };
    

关于javascript - 在事件监听器函数中无法访问 React hooks 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55326406/

相关文章:

Javascript 递增计数器 onclick 事件

javascript/jquery - 避免重复评估条件

javascript - 相当于 Deno 中的 `util.inspect`

javascript - 如何删除光标前的值 - React

javascript - 具有相似 id 模式的按钮的单个 onclick 函数 - JavaScript

javascript - 在循环中添加事件监听器 (mouseenter),但仅在 1500 毫秒后触发 - 清除超时问题

javascript - 引导箱验证

javascript - 上传空文件时无法读取未定义的属性

javascript - Antd 多重选择删除不再出现在选项列表中的值

reactjs - react PDF : Cannot use the packages to show static PDF file