簡體   English   中英

useEffect 中的狀態隨延遲變化

[英]State inside useEffect changing with delay

我正在嘗試根據在 React 組件的輸入中輸入的內容( text )來操作 DOM:

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

function App() {
  const [text, setText] = useState("Initial value");

  function handleChange(event) {
    setText(event.target.value);
  }

  useEffect(() => {
    function handleKeypress(event) {
      console.log("text", text);
      // do something with the DOM with text
    }

    document.addEventListener("keydown", handleKeypress);

    return () => {
      document.removeEventListener("keydown", handleKeypress);
    };
  }, [text]);

  return (
    <div id="keys">
      <input type="text" onChange={handleChange} value={text} />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

它有效,但發生了一些奇怪的事情。 除非第二次觸發keydown ,否則text不會改變。

例如,如果您按下aconsole.log("text", text)將記錄Initial value 它不會記錄a . 我認為有某種延遲。

為什么是這樣? 以及如何更改代碼以便console.log("text", text)記錄正在按下的鍵?

實時代碼: https ://codesandbox.io/s/react-hooks-useeffect-forked-sfujxi?file=/src/index.js

注意:我使用事件監聽器的原因是我希望代碼也能在我按下Ctrl + Key時運行(在這種情況下text不會改變)。

看起來這是因為在組件的下一次渲染中更新了text狀態,但是事件塊仍在使用更新前的舊值。

盡量不要使用事件偵聽器,但讓useEffect捕獲text狀態的更改,它應該記錄正確的輸入(當text更改時):

  useEffect(() => {
    console.log("text", text);
  }, [text]);

或者,如果目標是記錄按下的鍵,也許考慮只用event捕獲它,因為event將具有按下的鍵的值。

這種方法不需要從text狀態中讀取,而是可以考慮將捕獲的值設置為在其他一些組件中顯示的狀態。

  useEffect(() => {
    function handleKeypress(event) {
      console.log(event.keyCode);
    }
    document.addEventListener("keydown", handleKeypress);
    return () => {
      document.removeEventListener("keydown", handleKeypress);
    };
  }, []);

考慮到您在問題中提供的注釋如果您希望handleKeypress函數在用戶按下組合鍵(例如Ctrl + Key )時運行,您可以使用event.ctrlKey屬性檢查是否按下了 Ctrl 鍵。

function handleKeypress(event) {
  if (event.ctrlKey) {
    console.log("Ctrl + Key was pressed");
  }
}

例如,如果您想檢查特定的組合鍵,要檢查Ctrl + S ,您可以使用event.key property來做到這一點。

function handleKeypress(event) {
  if (event.ctrlKey && event.key === "s") {
    console.log("Ctrl + S was pressed");
  }
}

暫無
暫無

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

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