RangeError Diagnostics: Maximum Call Stack Size Exceeded in React KeyEscapeUtils

Background

Our webapp is written using React and Redux using official bind-redux bindings. Another main library used in this web application is PaperJS . We recently translated this into a Redux application, although we used React for a while.

Problem

Sometimes an update (usually every other update) causes

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)

Here is the source code of React where it does not work:

return ('' + keySubstring).replace(unescapeRegex, function (match) {
  return unescaperLookup[match];
});

and in the context of:

/**
 * 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];
  });
}

, , , - React , stacktrace - , , . , , , - setState.

? , , ? , KeyEscapeUtils?

+6
2

, , , , , , , , .

, " " chrome dev, , , .

, setState. , setState componentDidUpdate render. , .

+2

unescape React ( 15.4) , . react/lib/flattenChildren.js:

function flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID) {
  // We found a component instance.
  if (traverseContext && typeof traverseContext === 'object') {
    var result = traverseContext;
    var keyUnique = result[name] === undefined;
    if (process.env.NODE_ENV !== 'production') {
      if (!ReactComponentTreeHook) {
        ReactComponentTreeHook = require('./ReactComponentTreeHook');
      }
      if (!keyUnique) {
        process.env.NODE_ENV !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0;
      }
    }
    if (keyUnique && child != null) {
      result[name] = child;
    }
  }
}

flattenSingleChildIntoContext - , . :

process.env.NODE_ENV !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0;

, . , - . , , Chrome Dev Tools. console.log , :

  if (!keyUnique) {
    console.log('key is not unique', name);
    throw new Error('Key is not unique');
  }

, , .

+3

Source: https://habr.com/ru/post/1016009/


All Articles