javascript 如何修复React中的以下“太多重新渲染错误”?

rnmwe5a2  于 2022-11-27  发布在  Java
关注(0)|答案(5)|浏览(126)

我试图将字符串数组keys呈现到React组件中。keys是用户按下的键(但为了便于本示例,我只是将它们硬编码)。

import { useState } from "react";
import * as ReactDOM from "react-dom";

let keys = ["a", "b"];

function App() {
  let [keysState, setKeysState] = useState([]);

  setKeysState((keysState = keys));

  return (
    <div>
      {keysState.map((key) => (
        <li>{key}</li>
      ))}{" "}
    </div>
  );
}

const rootElement = document.getElementById("root");

ReactDOM.createRoot(rootElement).render(<App />);

但我得到这个错误:
重新呈现太多。React会限制呈现的数目,以防止无限循环。
我知道我可以通过创建onClick处理程序来避免这个错误...但是我不想在单击时显示keysState。我希望它在keys更改时立即显示并重新呈现。
实时代码:https://codesandbox.io/s/react-18-with-createroot-forked-vgkeiu?file=/src/index.js:0-504

ijxebb2r

ijxebb2r1#

当页面加载时,调用setKeysState函数并更新状态,更新reactjs中的状态会导致重新呈现,并且它会无限地重复此操作,这会产生Too many re-renders错误。
只需将一个初始值传递给useState()钩子来初始化状态。如下所示:

let [keysState, setKeysState] = useState(keys);
798qvoo8

798qvoo82#

检查这个代码片段,我还添加了在用户输入时向keysState添加值的逻辑。
https://codesandbox.io/s/react-18-with-createroot-forked-dhkrk3?file=/src/index.js

gmxoilav

gmxoilav3#

useState的工作原理似乎有点混乱。你会得到无限的刷新,因为如果状态发生变化,组件会重新呈现。这里发生的是,你加载组件,初始化你的状态并设置值,这会触发重新呈现,并在循环中运行。要解决这个问题,只需将初始值设置为键,而不是[]
"没人提起的事"

  • 使状态为常量,因为我认为,没有一个很好的理由来改变它是一个状态的事实,如果你想改变它的值,你可以使用setKeysState
  • setKeysState是一个函数,您可以使用keysState的新值调用该函数,因此,除了setKeysState(newValue)之外,不要更改该状态的值。您传递的是一个函数,我将其描述为“function”,您只需传递值

解决方法:

const [keysState, setKeysState] = useState(keys);
n7taea2i

n7taea2i4#

虽然@monim的回答很棒,但我觉得如果你不需要setKeysState,就不需要useState钩子

import { useState } from "react";
import * as ReactDOM from "react-dom";

function App(props) {
  const keys = props.keys

  return (
    <div>
      {keys.map((key) => (
        <li>{key}</li>
      ))}
    </div>
  );
}

const rootElement = document.getElementById("root");

ReactDOM.createRoot(rootElement).render(<App />);
6uxekuva

6uxekuva5#

这段代码有很多不同的问题,这让我可以告诉你,你还没有得到React钩子的方法。
首先,你不需要写这个setKeyState函数,当被调用时,useState钩子会返回它。

第二,如果你想给你的keyState提供一个初始值,你应该使用setState钩子,就像这样:

const [keyState, setKeyState] = useState(["a","b"]);

这将创建keyState变量,并使用["a","b"]对其进行初始化,同时提供setKeyState函数。
我相信这是这段代码的主要问题。这种冗余导致了永久的重新渲染。
最后,你应该有一些方法来对状态变化做出React,这将由useEffect钩子给出。

useEffect(() => {
    // Things to perform when `stateKeys` changes
},[stateKeys])

这个钩子接收到的第二个参数[stateKeys]就是为了防止永久性的重新呈现,它告诉钩子只有在这个数组中的变量改变时才运行。
在我看来,请不要介意我说的话,你在React的做事方式中遗漏了一些东西。特别是在React Hooks方面。我建议你再读一遍文档:
https://reactjs.org/docs/hooks-state.html

相关问题