anthonyshort / deku

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

`context` doesn't get passed down regular DOM nodes (v2.0.0-rc5) #323

Closed rstacruz closed 8 years ago

rstacruz commented 8 years ago

Given these two components that nest each other, I'm expecting context to travel down to Button.

var Button = {
  render ({ props, context }) {
    console.log('button context:', context)
    return <button>{ props.label }</button>
  }
}
var Form = {
  render ({ props, context }) {
    console.log('form context:', context)
    return <div>
      <h2>My form</h2>
      <div class='actions'><Button label='press me!' /></div>
    </div>
  }
}
render = dom.createRenderer(document.body)
context = { hello: 'there' }
render(<Form />, context)

But in actuality, only form sees it:

form context: { hello: 'there' }
button context: undefined

If you change Form.render to remove the wrapping div.actions, it works:

    return <div>
      <h2>My form</h2>
      <Button label='press me!' />
    </div>
anthonyshort commented 8 years ago

Just added tests for this and they're passing. Published 2.0.0-rc6.

rstacruz commented 8 years ago

I'm still getting issues of context being undefined. I'll see if i can make a reduced test case

rstacruz commented 8 years ago

Okay, it only happens on the second render.

const MyComponent = {
  render ({ context }) {
    console.log('level 2 render:', context)
    return <div>hello</div>
  }
}

const AppRoot = {
  render ({ context }) {
    console.log('level 1 render:', context)
    return <div class='app'>
      <MyComponent />
    </div>
  }
}

Render it twice:

let render = dom.createRenderer(document.body)

// Render twice
render(<AppRoot />, { isContext: true })
render(<AppRoot />, { isContext: true })
level 1 render: { isContext: true }
level 2 render: { isContext: true }
level 1 render: { isContext: true }
level 2 render: undefined    :(