Reactjs 如何在EventHandler中使用状态变量(useState)

Reactjs 如何在EventHandler中使用状态变量(useState),reactjs,react-hooks,Reactjs,React Hooks,我有一个React函数组件,它接收一个带有useState()变量的prop。这很好,但是如果我在EventListener中使用它,它不会得到更新。我尝试了以下方法,但仍然不起作用 也许有人能解释原因 谢谢 我希望x是更新后的数字,但它始终具有EventHandler初始设置的值 import React, { useState, useEffect } from "react"; import ReactDom from "react-dom"; const App = () =>

我有一个React函数组件,它接收一个带有useState()变量的prop。这很好,但是如果我在EventListener中使用它,它不会得到更新。我尝试了以下方法,但仍然不起作用

也许有人能解释原因

谢谢

我希望x是更新后的数字,但它始终具有EventHandler初始设置的值

import React, { useState, useEffect } from "react";
import ReactDom from "react-dom";

const App = () => {
   const [num, setNum] = useState(50);

  return (
    <div>
       <button onClick={() => setNum(prev => prev + 1)}>Test</button>
       <div>{num}</div>
       <Child num={num} />
    </div>
  );
};

const Child = ({ num }) => {
  let x = 0;
  const md = () => {
  console.log(num, x);
};

useEffect(() => {
x = num;
  }, [num]);

useEffect(() => {
    document.getElementById("box").addEventListener("mousedown", md);

    return () => {
      document.removeEventListener("mousedown", md);
    };
  }, []);

  return <div id="box">click {num}</div>; 
};

ReactDom.render(<App />, document.getElementById("app"));
import React,{useState,useffect}来自“React”;
从“react dom”导入react dom;
常量应用=()=>{
const[num,setNum]=useState(50);
返回(
setNum(prev=>prev+1)}>Test
{num}
);
};
常量Child=({num})=>{
设x=0;
常数md=()=>{
console.log(num,x);
};
useffect(()=>{
x=num;
},[num]);
useffect(()=>{
document.getElementById(“框”).addEventListener(“mousedown”,md);
return()=>{
文件。removeEventListener(“mousedown”,md);
};
}, []);
返回单击{num};
};
ReactDom.render(,document.getElementById(“app”);

您的
子对象的每个渲染将获得一个新的
x
、一个新的
props
对象等。但是,您只绑定一次事件侦听器,因此只捕获初始的
props.num

两种修复方法:

num
更改时重新绑定事件侦听器,方法是将
num
作为依赖项传递给您,以绑定事件侦听器:

const Child = ({ num }) => {

  useEffect(() => {
    // no need to define this in main function since it is only
    // used inside this effect
    const md = () => { console.log(num); };
    document.getElementById("box").addEventListener("mousedown", md);

    return () => {
      document.removeEventListener("mousedown", md);
    };
  }, [num]);

  return <div id="box">click {num}</div>; 
};

嗨,谢谢你的回答。如果我使用选项1,我是否会创建大量不必要的EventListener和大量内存?版本2似乎更好。我的解决方法是使用一个值为num state的隐藏html输入字段。但这当然很难看。版本一在每次添加新的事件侦听器时都会删除旧的事件侦听器(因为效果会返回一个函数来删除侦听器)。低频变化也可以,比如从按钮时钟触发的变化。选项2中的模式更适合高频变化,总体上更通用。这可能就是我要用的
const Child = ({ num }) => {
  const numRef = useRef();  // will be same object each render
  numRef.current = num; // assign new num value each render

  useEffect(() => {
    // no need to define this in main function since it is only
    // used inside this effect
    // binds to same ref object, and reaches in to get current num value
    const md = () => { console.log(numRef.current); };
    document.getElementById("box").addEventListener("mousedown", md);

    return () => {
      document.removeEventListener("mousedown", md);
    };
  }, []);

  return <div id="box">click {num}</div>; 
};