typescript 如何停止React useEffect内部的无限循环?

u0njafvf  于 2022-11-30  发布在  TypeScript
关注(0)|答案(2)|浏览(162)

我希望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的第二个参数传递给React.useEffect会停止无限循环,但事实并非如此。
为什么会这样?如何解决?
实时代码:https://codesandbox.io/s/changing-props-on-react-root-component-forked-eu16oj?file=/src/index.tsx

stszievb

stszievb1#

最好的方法是将非React代码集成到应用程序中,这样按键后的状态设置就变得自然而简单了。

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状态setter--无论从哪个Angular 看,这都是非常丑陋的。我想你可以把它赋给一个外部变量:

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;
brgchamk

brgchamk2#

您需要将两个参数传递给useEffect:
1 =〉包含连接到该系统的安装代码的安装函数。它应该返回包含从该系统断开连接的清理代码的清理函数。2 =〉依赖项列表,包括在这些函数中使用的组件的每个值。

相关问题