javascript - 如何解决无限重新渲染问题?

标签 javascript reactjs

错误:超出最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制嵌套更新的数量以防止无限循环。

找到了我的问题的答案,但是,我还是不明白如何解决这个问题?

const { useState } = React,
      { render } = ReactDOM

function App() {
  const [visible, setVisible] = useState(false);
  const [visible2, setVisible2] = useState(false);

  const arr1 = {
    company: [
      {
        id: "random1",
        companyName: "Apple"
      },
      {
        id: "random2",
        companyName: "Samsung"
      }
    ]
  };

  const onDataHandle = () => {
    return arr1.company.map(items => {
      return (
        <div>
          <span key={items.id}>
            {items.companyName}
            <span onClick={onHandleVisible}>Details</span>
          </span>
          <br />
        </div>
      );
    });
  };

  const onHandleVisible = () => {
    setVisible(!visible);
  };

  const onHandleVisible2 = () => {
    setVisible2(!visible2);
  };

  return (
    <div className="App">
      <button onClick={onHandleVisible2}>Show</button>
      {visible && onDataHandle()}
    </div>
  );
}

render (
  <App />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

我知道这是由于无休止的重新渲染造成的,但是解决方案是什么?

最佳答案

您的代码逻辑存在多个问题(我必须说,这并不完全清楚):

  • 显示按钮onClick触发器onHandleVisible2设置 visible2 的回调状态变量为true ,但是您的代码中没有任何内容取决于该状态变量,因此什么也没有发生
  • 区 block {visible && onDataHandle()}应该触发onDataHandle() (由于上述原因,这种情况永远不会发生 - visible 保持等于 false ),但是 onDataHandle() (即使尝试返回一些 JSX)不会在 <App /> 内添加任何要渲染的内容因为它不是 ReactJS 组件
  • (次要的)如果您有意 onDatahandle()是返回一些组件,用额外的 <div> 包裹你的跨度没有多大意义。

解决上述所有问题后,您会得到一些东西,例如:

const { useState } = React,
      { render } = ReactDOM

function App() {
  const [visible, setVisible] = useState(false);
  const [visible2, setVisible2] = useState(false);

  const arr1 = {
    company: [
      {
        id: "random1",
        companyName: "Apple"
      },
      {
        id: "random2",
        companyName: "Samsung"
      }
    ]
  };

  const Data = () => (
    <div>
      {
        arr1.company.map(items => (
          <span key={items.id}>
            {items.companyName}
            <span onClick={onHandleVisible}>Details</span>
            {visible && <span>There go {items.companyName} details</span>}
            <br />
          </span>))
       }
    </div>
  )

  const onHandleVisible = () => {
    setVisible(!visible);
  };

  const onHandleVisible2 = () => {
    setVisible2(!visible2);
  };

  return (
    <div className="App">
      <button onClick={onHandleVisible2}>Show</button>
      {visible2 && <Data />}
    </div>
  );
}

render (
  <App />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

注意上述代码块中的一个重要问题仍未解决:您在整个应用程序中使用了单个变量 ( visible ),因此如果您决定控制 details 的可见性对于每个项目,您将无法使用当前的方法来做到这一点。但这是一个完全不同的问题,您可以将其作为单独的问题发布。

关于javascript - 如何解决无限重新渲染问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59892554/

相关文章:

javascript - d3 缩放到边界框 II 缩放时滚动会引发错误

javascript - React 元素类型无效

reactjs - React js typescript 字符串数组变量

javascript - 如何在 jquery 中推送这样的对象?

c# - 使用 MVC Controller 作为 webService

javascript - Quickblox Javascript SDK + Angular + webRTC - Firefox 错误 : SecurityError: The operation is insecure

javascript - React.js : disable DateTime when changed to the past

javascript - 在 react 测试渲染器中调用 prop 回调不会更新钩子(Hook)

reactjs - 为什么在没有 Internet 的情况下启动应用程序时没有正确触发 React Native 的 NetInfo?

JavaScript 保留字 : "preset"