[英]How to stop the infinite loop inside this React useEffect?
我希望 React 从非 React 上下文呈现按键,更具体地说是字符串数组keys
:
import * as React from "react";
import { render } from "react-dom";
let keys: string[] = [];
function handleKeypress(event: any) {
keys.push(event.key);
console.log(keys);
// there will be more code here unrelated to React.
}
document.removeEventListener("keypress", handleKeypress);
document.addEventListener("keypress", handleKeypress);
function App() {
const [keysState, setKeysState] = React.useState<string[]>([]);
React.useEffect(() => {
function updateKeysState() {
setKeysState([...keys]);
}
// if you uncomment this, the code inside useEffect will run forever
// updateKeysState()
console.log("Hello world");
}, [keysState]);
return (
<div>
{keys.map((key: string, id) => (
<li key={id}>{key}</li>
))}
</div>
);
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
我几乎完成了……问题是, React.useEffect
中的代码在无限循环中运行。
我认为将[keysState]
作为第二个参数传递给React.useEffect
会停止无限循环。 但它没有。
为什么会这样以及如何解决?
实时代码: https://codesandbox.io/s/changing-props-on-react-root-component-forked-eu16oj?file=/src/index.tsx
最好的方法是将非 React 代码集成到应用程序中,这样设置 state 作为按键的结果是自然而微不足道的。
function App() {
const [keys, setKeys] = React.useState<string[]>([]);
useEffect(() => {
function handleKeypress(event: KeyboardEvent) {
setKeys([...keys, event.key]);
// There will be more code here that's unrelated to React.
}
document.addEventListener("keypress", handleKeypress);
return () => {
document.removeEventListener("keypress", handleKeypress);
};
}, []);
然后你可以完全放弃你当前的React.useEffect
(和它的无限循环)。
如果这不是一个选项,您将不得不从 React 外部触发 React state setter - 无论您怎么看,这都会非常难看。 我想你可以将它分配给一个外部变量:
let setKeysOuter;
function handleKeypress(event: KeyboardEvent) {
setKeysOuter?.(keys => [...keys, event.key]);
// There will be more code here that's unrelated to React.
}
function App() {
const [keys, setKeys] = React.useState<string[]>([]);
setKeysOuter = setKeys;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.