[英]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
不會改變。
例如,如果您按下a
, console.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.