Lucifier129 / react-lite

An implementation of React v15.x that optimizes for small script size

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error relating to vchildren

roastlechon opened this issue · comments

Context is that we use:

  • webpack2
  • webpack-dll
  • reactrouter
  • split bundles to deliver react components
page.route.js:168 TypeError: Cannot read property 'vchildren' of undefined
    at destroyVelem (webpack:///./~/react-lite/dist/react-lite.common.js?:363:25)
    at destroyVnode (webpack:///./~/react-lite/dist/react-lite.common.js?:150:9)
    at destroyVelem (webpack:///./~/react-lite/dist/react-lite.common.js?:367:9)
    at destroyVnode (webpack:///./~/react-lite/dist/react-lite.common.js?:150:9)
    at destroyVcomponent (webpack:///./~/react-lite/dist/react-lite.common.js?:492:5)
    at destroyVnode (webpack:///./~/react-lite/dist/react-lite.common.js?:153:9)
    at destroyVcomponent (webpack:///./~/react-lite/dist/react-lite.common.js?:492:5)
    at destroyVnode (webpack:///./~/react-lite/dist/react-lite.common.js?:153:9)
    at destroyVcomponent (webpack:///./~/react-lite/dist/react-lite.common.js?:492:5)
    at destroyVnode (webpack:///./~/react-lite/dist/react-lite.common.js?:153:9)

We need more information to reproduce this problem, some dom-element created by react-lite have been removed unexpectedly would cause this error.

To give a bit more context... we have a page that is rendered dynamically going route to route (SPA).
Starting from one page to the other, it potentially has different components.

I'm having the same issue. The problem is here;

for (let i = 0, len = vchildren.length; i < len; i++) {

TypeError
undefined is not an object (evaluating 'vchildren.length')

function destroyVelem(velem, node) {
    let { props } = velem
    let { vchildren, childNodes } = node
    for (let i = 0, len = vchildren.length; i < len; i++) {
        destroyVnode(vchildren[i], childNodes[i])
    }
    detachRef(velem.refs, velem.ref, node)
    node.eventStore = node.vchildren = null
}

I'm having a hard time replicating the issue with code as we only see it in production a couple of times a week. As its in minified code it's near impossible to trace. It looks like destroyVelem is being called on the same node twice.

The issue could be with this line node.eventStore = node.vchildren = null; Perhaps vchildren should be set to [] instead of null?

@zemaj

The error message told that vchildren is undefined, not null.

It seems like the real-dom was not created by virtual-dom, so it lost a custom property vchildren(access a nonexistent property from an object that may get undefined).

Ah yeah, good point.

We've added a sourcemap for the file, so next time it happens I'll be able to provide a full trace.

commented

I'm able to reproduce this issue in a project of mine, and it's hosted with a source map.

As far as I an tell, react-lite is not gracefully handling removing DOM nodes that it hasn't seen before. An advertising platform creates iframe nodes within our react component, but when react-lite tries to remove the component that contains the iframe, it blows up because there's no vchildren.

I may have pushed a fix by the time you view this comment.

Repro steps:

  • visit URL: stanza.co/timeline/nasa?embed=true&site=lakersnation
  • Ensure one of the ads render (the "Add things you <3" image should be covered by an advertisement.
  • Press the category hamburger menu and select "past"

Notice the JS error when the category switches.

commented

Yep. Fix was to move all DOM nodes that are touched by the 3rd party script outside of react-lite.

Basically, I just use el.innerHTML = ... to create the content.

commented

I can make a repro repo if you guys have difficulty with this, but it should be simple enough to replace a DOM node with vanilla JS in componentDidMount to surface this error.

Yeah, react-lite do not support mix real-dom to virtual-dom, except dangerouslySetInnerHTML..

commented

So, is this a won't fix?

Could you simply ignore DOM nodes that react-lite hasn't created, or could that result in a memory leak?

For keeping small, we are not going to handle the practice which is not recommended or unexpectedly, react-lite just follow the best-practice of react ;)

commented

@zemaj @Lucifier129 Please see my fork #108 that resolves this issue.