2017-03-24 34 views
6

Teşhis RangeError: aşılmaması Maksimum çağrı yığını boyutu KeyEscapeUtils

Bizim Webapp ile yazılır Arkaplan tepki tepki ve Redux resmi tepki-redux bağları kullanarak. Bu web uygulamasında kullanılan bir başka birincil kitaplık PaperJS. Kısa bir süre React kullanmış olmasına rağmen, bunu kısa bir süre önce Redux uygulaması olarak değiştirdik.

Sorun

bazen sütü (genellikle her yenileme) İşte

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) 

neden o da çöküyor Tepki kaynak kod:

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

ve bağlam içinde:

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

Bu, muhtemelen yanlış kullanıyorum bir yerde kodumda React olduğunu, ancak stacktrace kendi kodlarımdan herhangi bir başvuru içermediğinden, ne arayacağımı bilmiyorum. Yeniden oluşturma işleminin sonsuz bir döngüsü gibi görünüyor ve hatalı bir şekilde setState numaralı çağrıya bağlı olabileceğinden şüpheleniyorum.

benim şüphe ihtimali var mı Soru? Kendi kod tabanımın oldukça kapsamlı olması nedeniyle bu sorunu nasıl daha fazla teşhis edebilirim? Bunun KeyEscapeUtils'de başarısız olduğu ne anlama geliyor?

+0

Bu işlevin nerede kullanıldığını, ideal olarak onu kullanan tüm bileşeni ekleyebilir misiniz? Hatanın kaynağı büyük olasılıkla daha yüksektir. –

cevap

2

Başarısız bir yer olduğunu sanmıyorum, çünkü sonsuz bir döngüde yakalanmış görünüyorsunuz ve bu sadece çağrı yığını sınırının aşıldığı noktaya dönüşüyor.

Tanılamak için, henüz durdurulmamışsa, chrome dev araçlardaki 'Exceptions on Exceptions' özelliğini açmayı ve duraklatıldığında kendi kodunuz için yığın izlemeyi daha fazla araştırmayı deneyebilirim.

Yanlış setState çağrılarının buna neden olabileceğini biliyorsunuzdur. Örneğin, setState öğesini componentDidUpdate öğesinde işaretlenmemişse veya oluşturuyorsanız. Bu sadece bazen olur merak ediyorum.

+0

Gerçekten 'componentDidUpdate' içinde setState 'için bir çağrı yapıldı. Sorunu biriyle çözene kadar Bileşenleri React bileşenini yorumlayarak hangi bileşenin suçlu olduğunu tespit edebildim. Tüm 'componentDidUpdate's için bir denetimli inceleme de başlamak için iyi bir yerdir. –

3

React (sürüm 15.4) kaynak koduyla unescape arandı ve kullanıldığı tek bir yer bulduk. Dosya react/lib/flattenChildren.js geçerli:

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; 
    } 
    } 
} 

O flattenSingleChildIntoContext ise - bu sizin yığın izlemesi gösterilir tam olarak nasıl.

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; 

maksimum çağrı yığını hata yalnızca geliştirme modunda oluşur anlamına gelir: problemle satır bir uyarı göstermeye çalışır. Sorun şu ki, aynı anahtarla iki veya daha fazla öğe oluşturuyorsunuz. Hangi anahtarın, Chrome Dev Tools'da bu satırda kesme noktası kullanabileceğinizi bilmek.Yoksa orada console.log ekleyip tam orda yürütme durur, böylece istisna atabilir:

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

anahtar size yinelenen anahtar ile unsurlara sahip bir yer bulmak mümkün olacak bu şekilde döneriz.

İlgili konular