我希望Reaction呈现来自非Reaction上下文的按键,更具体地说是字符串数组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 代码集成到App中,以便通过按键来设置状态是自然和琐碎的.

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(以及它的无限循环).

如果这不是一个选项,您将不得不从Reaction外部触发Reaction状态设置器--无论从哪种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;

Javascript相关问答推荐

微软Edge编辑和重新发送未显示""

网页自检测外部元素无法加载

使用i18next在React中不重新加载翻译动态数据的问题

为什么我的列表直到下一次提交才更新值/onChange

如何在Obsidian dataview中创建进度条

Chromium会将URL与JS一起传递到V8吗?

在拖放时阻止文件打开

如何从URL获取令牌?

实现JS代码更改CSS元素

ChartJs未呈现

查询参数中的JAVASCRIPT/REACT中的括号

如何在.NET Core中将chtml文件链接到Java脚本文件?

Nextjs 13.4 Next-Auth 4.2登录(&Quot;凭据&,{});不工作

<;img>;标记无法呈现图像

如何修复错误&语法错误:不能在纯react 项目中JEST引发的模块&之外使用导入语句?

rxjs在每次迭代后更新数组的可观察值

在点击链接后重定向至url之前暂停

在不使用AJAX的情况下将JavaScript数组值传递给Laravel控制器?

JavaScript structuredClone在Chrome/Edge中获得了非法调用,但在NodeJS中没有

如何在通过JavaScript添加图像后将其删除?