【问题标题】:Maximum call stack size exceeded from loop循环超出最大调用堆栈大小
【发布时间】:2021-05-20 17:42:03
【问题描述】:

我正处于制作使用矩形的矩形 SVG 的早期阶段。我正在使用以 8 为增量获取所有 RGB 颜色的循环来生成像素的颜色。返回的数组中有 32,768 <rect />。该代码产生了预期的结果,但是我得到一个错误:

Maximum call stack size exceeded
getTypeSymbol (react_devtools_backend.js:4828)

火狐

too much recursion

据我所知,这不是递归问题,函数似乎没有重新加载。我认为这与数组的大小有关。

关于我应该在这里做什么的任何想法,我以前从未见过这个问题。

function PixelColour() {
  console.log("start");
  let counter = 0;
  let x = 0;
  let y = 0;

  const colours = [];

  for (let red = 0; red < 256; red += 8) {
    for (let green = 0; green < 256; green += 8) {
      for (let blue = 0; blue < 256; blue += 8) {
        counter++;

        if (x < 256) {
          x++;
        } else {
          x = 0;
        }

        if (x === 256) {
          y++;
        }

        colours.push(
          <rect
            key={counter}
            x={x}
            y={y}
            height="1"
            width="1"
            style={{ fill: `rgb(${red}, ${green}, ${blue})` }}
          />
        );
      }
    }
  }

  return <Fragment>{colours}</Fragment>;
}

class Colours extends React.Component {
  render() {
    return (
      <div>
        <svg width="256" height="128" style={{ border: "2px solid black" }}>
          <PixelColour />
        </svg>
      </div>
    );
  }
}

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    问题本身不是您的函数重新加载(或重新渲染);你在 React 本身中遇到了递归。特别是 React devtools 尝试协调 DOM 以构建组件映射的方式。

    这实际上并不容易在代码沙盒上复制,因为它似乎使用的是实验版本的 devtools,而且这个错误只会在热重载时出现。堆栈跟踪是scheduleFibersWithFamiliesRecursively,但在我安装了标准devtools 扩展的本地机器上,当组件挂载时我得到mountFiberRecursively

    我做了一些挖掘,发现了这个 github 问题,以及一个解决它的 PR,它似乎暂时被放弃了。 也许如果你去轻推他们,他们可能会再看一眼:

    Getting maximum call stack exceeded on backend.js when rendering many elements.

    Refactored backend renderer to remove most of the recursion

    与此同时,您所能做的就是禁用 devtools 扩展。我要补充一点,即使禁用它,这个组件也需要几秒钟才能安装在我的本地机器上。如果您不将计算从渲染周期(函数体)中取出,那么它将在每次渲染上运行。您正在尝试安装成千上万个 DOM 节点,这些节点永远不会以高性能运行 - 即使上面的 PR 也只假设限制为 15000。

    我认为一个更好的主意是1)如果可以的话,最好提前计算好这个值,最好是硬编码的数据,而不是靠近 UI 线程,并且 2) em> 绘制到画布而不是在 DOM 中创建节点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-24
      • 2015-12-29
      • 2017-12-27
      • 2020-12-06
      • 1970-01-01
      相关资源
      最近更新 更多