anthonyshort / deku

Render interfaces using pure functions and virtual DOM
https://github.com/anthonyshort/deku/tree/master/docs
3.41k stars 130 forks source link

Re-render throws an error (v2.0.0-rc6) #339

Closed sukazavr closed 8 years ago

sukazavr commented 8 years ago

Example code:

import { element, dom } from 'deku'

import * as view1 from 'views/1'
import * as view2 from 'views/2'

const app = document.getElementById('app')

const render = dom.createRenderer(app)

function loadAndRender (path) {
    let View = path === 1 ? view1 : view2
    render(<View />)
}

document.getElementById('one').onclick = e => {
    e.preventDefault()
    loadAndRender(1)
}

document.getElementById('two').onclick = e => {
    e.preventDefault()
    loadAndRender(2)
}

First click on either link is successful, but click on the opposite link throws an exception:

Uncaught TypeError: Cannot read property 'length' of undefined
    removeThunks @ bundle.js:591
    removeThunks @ bundle.js:592
    replaceNode @ bundle.js:564
    rawCase @ bundle.js:1854
    (anonymous function) @ bundle.js:1751
    (anonymous function) @ bundle.js:767
    (anonymous function) @ bundle.js:505
    update @ bundle.js:1002
    (anonymous function) @ bundle.js:1017
    loadAndRender @ bundle.js:844
    document.getElementById.onclick @ bundle.js:855

image

There is the test build: test-build.zip

gillstrom commented 8 years ago

I am getting this as well.

anthonyshort commented 8 years ago

Thanks for the detailed issue. I'll get this fixed up today with some tests.

anthonyshort commented 8 years ago

Easy fix for this. It's available in rc7. Thanks for submitting the issue :dancer:

anthonyshort commented 8 years ago

It was caused by the renderer trying to recurse down into the vnodes to remove all the components, but not accounting for text nodes.

sukazavr commented 8 years ago

Thank you! I appreciate your promptness :-)

rstacruz commented 8 years ago

Not sure if related, but I'm getting a similar error:

Uncaught TypeError: Cannot read property 'childNodes' of undefined
      updateChildren: function updateChildren(changes) {
        // Create a clone of the children so we can reference them later
        // using their original position even if they move around
        var childNodes = Array.prototype.slice.apply(DOMElement.childNodes); // <--