簡體   English   中英

為什么 Native DOM 事件總是重置 React 組件 state

[英]Why Native DOM event always reset React Component state

我知道Synthetic Event而不是原生的 dom event應該是 React App 中處理交互的方式,但我想知道為什么行為如此奇怪。 當 React 事件運行良好時,dom 事件總是將 state 重置為初始 state。

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

發生這種情況是因為您的本機事件處理程序仍然關閉第一次渲染后可用的num值(該值為 0)。 您需要在每個 state 更新中添加和刪除本機事件偵聽器,才能像這樣工作:-

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

正如@Mahdi 指出的那樣,另一種方法可能是在 state 更新器 function 中使用回調。 這將允許您在之前的 state 的基礎上獲得新的 state。 但是本機事件偵聽器可以訪問的num的值仍然為 0。您可以通過在clickMe中執行console.log(num)來驗證這一點。

function clickMe() {
    setNum(prevNum => prevNum + 1); // <-- you need this
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM