诊断RangeError:React KeyEscapeUtils中超出了最大调用堆栈大小

Sco*_*y H 6 stack-overflow setstate reactjs redux react-redux

背景

我们的webapp使用官方的react-redux绑定编写React和Redux.此Web应用程序中使用的另一个主要库是PaperJS.我们最近将其转换为Redux应用程序,尽管它已经使用了React一段时间.

问题

有时刷新(通常每隔一次刷新)会导致一次

RangeError: Maximum call stack size exceeded
at String.replace (<anonymous>)
at Object.unescape (KeyEscapeUtils.js:49)
at flattenSingleChildIntoContext (flattenChildren.js:32)
at flattenChildren.js:53
at traverseAllChildrenImpl (traverseAllChildren.js:69)
at traverseAllChildrenImpl (traverseAllChildren.js:85)
at traverseAllChildren (traverseAllChildren.js:157)
at flattenChildren (flattenChildren.js:52)
at ReactDOMComponent._reconcilerUpdateChildren (ReactMultiChild.js:209)
at ReactDOMComponent._updateChildren (ReactMultiChild.js:315)
Run Code Online (Sandbox Code Playgroud)

这是它失败的React源代码:

return ('' + keySubstring).replace(unescapeRegex, function (match) {
  return unescaperLookup[match];
});
Run Code Online (Sandbox Code Playgroud)

并在上下文中:

/**
 * Unescape and unwrap key for human-readable display
 *
 * @param {string} key to unescape.
 * @return {string} the unescaped key.
 */
function unescape(key) {
  var unescapeRegex = /(=0|=2)/g;
  var unescaperLookup = {
    '=0': '=',
    '=2': ':'
  };
  var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1);

  return ('' + keySubstring).replace(unescapeRegex, function (match) {
    return unescaperLookup[match];
  });
}
Run Code Online (Sandbox Code Playgroud)

这可能表明某些地方我在我的代码中滥用了React,但由于堆栈跟踪不包含对我自己的代码的引用,我不知道该寻找什么.它似乎是一个无限循环的重新渲染,我怀疑它可能是由于调用不当而导致的setState.

问题

我怀疑可能吗?鉴于我自己的代码库相当广泛,我怎样才能进一步诊断这个问题呢?这在KeyEscapeUtils中失败意味着什么?

TLa*_*add 2

我认为它失败的地方并不重要,因为您似乎陷入了无限循环,而这恰好是超出调用堆栈限制的地方。

为了进行诊断,我会尝试在 chrome 开发工具中打开“异常暂停”(如果尚未打开),并在暂停时进一步查找堆栈跟踪以查找您自己的代码。

您是正确的,不正确的 setState 调用可能会导致此问题。例如,如果您在 componentDidUpdate 或 render 中调用 setState 时未选中。奇怪的是,这种情况只是偶尔发生。