【问题标题】:Why Native DOM event always reset React Component state为什么 Native DOM 事件总是重置 React 组件状态
【发布时间】:2021-05-21 02:23:31
【问题描述】:

我知道 Synthetic Event,而不是 native dom event,应该是 React App 中处理交互的方式,但我想知道为什么这种行为是太奇怪了。当 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>
  );
}

完整的项目可以在这里打开https://stackblitz.com/edit/react-wqrmcu?file=src/App.js

【问题讨论】:

    标签: javascript reactjs use-effect use-state


    【解决方案1】:

    发生这种情况是因为您的本机事件处理程序仍然关闭了第一次渲染后可用的 num 值(该值为 0)。您需要在每次状态更新时添加和删除本机事件侦听器才能像这样工作:-

      useEffect(() => {
        document.getElementById("app_btn").addEventListener("click", clickMe);
        return () =>
          document.getElementById("app_btn").removeEventListener("click", clickMe);
      }, [num]);
    

    正如@Mahdi 指出的那样,另一种方法可能是在状态更新器函数中使用回调。这将允许您在先前状态的基础上获得新状态。但是本机事件侦听器可以访问的num 的值仍然为0。您可以通过在clickMe 中执行console.log(num) 来验证这一点。

    【讨论】:

      【解决方案2】:
      function clickMe() {
          setNum(prevNum => prevNum + 1); // <-- you need this
        }
      

      【讨论】:

      • 谢谢,我确实找到了解决方案,但不知道为什么我的版本适用于 react 事件,而不适用于 dom 原生事件
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 2020-05-14
      • 2020-08-28
      • 1970-01-01
      相关资源
      最近更新 更多