Javascript 为什么本机DOM事件总是重置组件状态

Javascript 为什么本机DOM事件总是重置组件状态,javascript,reactjs,use-effect,use-state,Javascript,Reactjs,Use Effect,Use State,我知道在React应用程序中处理交互的方式应该是合成事件,而不是原生dom事件,但我想知道为什么这种行为如此奇怪。当React事件正常工作时,dom事件总是将状态重置为初始状态 import React, { useState, useEffect } from "react"; import "./style.css"; export default function App() { const [num, setNum] = useState(0

我知道在React应用程序中处理交互的方式应该是合成事件,而不是原生dom事件,但我想知道为什么这种行为如此奇怪。当React事件正常工作时,dom事件总是将状态重置为初始状态

import React, { useState, useEffect } from "react";
import "./style.css";

export default function App() {
  const [num, setNum] = useState(0);
  function clickMe() {
    setNum(num + 1);
  }
  useEffect(() => {
    document.getElementById("app_btn").addEventListener("click", clickMe);
    return () =>
      document.getElementById("app_btn").removeEventListener("click", clickMe);
  }, []);
  return (
    <div>
      <h1>Hello StackBlitz!</h1>
      <div>App {num}</div>
      <button id="app_btn">DOM click</button> <br />
      <button onClick={clickMe}>React Click</button>
    </div>
  );
}
import React,{useState,useffect}来自“React”;
导入“/style.css”;
导出默认函数App(){
const[num,setNum]=useState(0);
函数clickMe(){
setNum(num+1);
}
useffect(()=>{
document.getElementById(“app_btn”).addEventListener(“单击”,单击我);
return()=>
document.getElementById(“app_btn”).removeEventListener(“单击”,单击我);
}, []);
返回(
你好,斯塔克布里兹!
App{num}
DOM单击
反应点击 ); }

可以在此处打开完整项目,这是因为您的本机事件处理程序仍然在第一次渲染后可用的
num
值(该值为0)上关闭。您需要在每次状态更新时添加和删除本机事件侦听器,以使其正常工作:-

  useEffect(() => {
    document.getElementById("app_btn").addEventListener("click", clickMe);
    return () =>
      document.getElementById("app_btn").removeEventListener("click", clickMe);
  }, [num]);
另一种方法是在state updater函数中使用回调,正如@Mahdi指出的那样。这将允许您在先前状态的基础上获得新状态。但是本机事件侦听器可以访问的
num
的值仍然是0。您可以通过执行
console.log(num)
内的
clickMe

函数clickMe()来验证{
function clickMe() {
    setNum(prevNum => prevNum + 1); // <-- you need this
  }

setNum(prevNum=>prevNum+1);//Thansk,我实际上找到了解决方案,但不知道为什么我的版本使用react事件,而不是dom本机事件