控制台中的反应错误 - 输入长度超过 5 时超出最大更新深度

React error in console - Maximum update depth exceeded when input length is more than 5

我有一个输入组件,最多可以输入 5 个字符。当输入长度大于 5 时,显示消息 Limit Exceeds (only upto 5 characters accepted).

示例组件代码:

import { useEffect, useState } from "react";

export function ConditionalInput() {

  const [inputInfo, setInputInfo] = useState({ value: "", lengthCount: 0 });
  const [warningMessageVisible, setWarningMessageVisible] = useState(false);

  useEffect(() => {
    if (inputInfo.value.length > 5) {
      setInputInfo((s) => ({ ...s, lengthCount: 0 }));
    }
  }, [inputInfo, warningMessageVisible]);

  const onChange = ({ target }) => {
    setInputInfo((s) => ({ ...s, value: target.value }));
    if (target.value.length > 5) {
      setWarningMessageVisible(true);
    }
  };
  
  return (
    <div>
      <input type="text" value={inputInfo.value} onChange={onChange} />
      <div>Number of secrets: {inputInfo.lengthCount}</div>
      {warningMessageVisible && (
        <h3>Limit Exceeds (only upto 5 characters accepted)</h3>
      )}
    </div>
  );
}

在 UI 上一切正常,但在控制台中我可以看到一条错误消息在无限循环中打印,指出 - 超出最大更新深度

注意 - 上面的代码不是我正在使用的实际代码,而是它的模拟。它有同样的错误和工作

如何解决控制台中显示的错误?任何建议或答案表示赞赏

这是因为您添加了依赖数组 setInputInfo 只要 inputInfo 发生变化,您的 useEffect 就会触发。在 useEffect 中,您正在修改 inputInfo。所以基本上它是在创建一个无限循环,它将继续渲染视图。

要解决此问题,您可以从 useEffect 的依赖项数组中删除 inputInfo

这个问题发生在这个useEffect

useEffect(() => {
  if (inputInfo.value.length > 5) {
    setInputInfo((s) => ({ ...s, lengthCount: 0 }));
  }
}, [inputInfo, warningMessageVisible]);

此 useEffect 在 inputInfo 更改时始终 运行。所以你需要像这样删除useEffect处的inputInfo

useEffect(() => {
  if (inputInfo.value.length > 5) {
    setInputInfo((s) => ({ ...s, lengthCount: 0 }));
  }
}, [warningMessageVisible]);

您需要对代码进行以下更改:

  • 从 useEffect 依赖项中删除 inputInfo
  • 而不是使用 infoInput.lengthCount 使用 infoInput.value.length 来显示长度计数。

下面是工作代码

import { useEffect, useState } from "react";

export function ConditionalInput() {

  const [inputInfo, setInputInfo] = useState({ value: "", lengthCount: 0 });
  const [warningMessageVisible, setWarningMessageVisible] = useState(false);

  useEffect(() => {
    if (inputInfo.value.length > 5) {
      setInputInfo((s) => ({ ...s, lengthCount: 0 }));
    }
  }, [warningMessageVisible]);

  const onChange = ({ target }) => {
    setInputInfo((s) => ({ ...s, value: target.value }));
    if (target.value.length > 5) {
      setWarningMessageVisible(true);
    }
  };

  return (
    <div>
      <input type="text" value={inputInfo.value} onChange={onChange} />
      <div>Number of secrets: {inputInfo.value.length}</div>
      {warningMessageVisible && (
        <h3>Limit Exceeds (only upto 5 characters accepted)</h3>
      )}
    </div>
  );
}