jorgebucaran / hyperapp

1kB-ish JavaScript framework for building hypertext applications
MIT License
19.08k stars 780 forks source link

oncreate and conditionals #504

Closed mietennet closed 6 years ago

mietennet commented 6 years ago

if i'm doing that:

const Panel = (prop, children) => (
  <section oncreate={element => console.log('created', prop.id)}>
    {children}
    {prop.current && ' (active)'}
  </section>
)

const state = {
  panels: Array.from(new Array(10), (val, index) => index + 1),
  currentPanel: 1
}

const actions = {
  prevPanel: () => state => ({
    currentPanel: state.currentPanel > 0 ? state.currentPanel - 1 : 0
  }),
  nextPanel: () => state => ({
    currentPanel: state.currentPanel < state.panels.length - 1 ? state.currentPanel + 1 : state.panels.length - 1
  })
}

const view = (state, actions) => (
  <div>
      <button onclick={actions.prevPanel}>
          Prev
        </button>
        <button onclick={actions.nextPanel}>
          Next
        </button>

      <div>
        {state.panels.map((v, i) => (
          <Panel id={i} current={i === state.currentPanel}>
            This is Panel {v}
          </Panel>
        ))}
      </div>
  </div>
)

app(state, actions, view, root)

everything works as expected and i get a couple of "created x" at my console log

but if i'm changing to this, to render only the active panel:

const Panel = (prop, children) =>
  prop.current && (
    <section oncreate={element => console.log('created', prop.id)}>
      {children}
    </section>
  )

now i get one console log for the first element, then if i change state.currentPanel the app works as expected but without triggering the oncreate... so no further console line!

any ideas?

mietennet commented 6 years ago

gotcha, hyperapp recycles the section-element...

if i add a key to the element then it works as expected:

<section key={prop.id} oncreate={element => console.log('created', prop.id)}>

is this intended?

jorgebucaran commented 6 years ago

@mietennet Yes, definitely. 👍

zaceno commented 6 years ago

@mietennet Yup! This is exactly (one of) the purpose of keys: controlling when elements are destroyed/created vs reused.

mietennet commented 6 years ago

ok, thanks...

is it also intended, that i have to use oncreate inside my component-function but not like that:

<Panel id={i} current={i === state.currentPanel} oncreate={element => console.log('created', i)}>
  This is Panel {v}
</Panel>
zaceno commented 6 years ago

Yeah kind of intended: oncreate is about elements, and only means something when attached to a vnode. Your Panel is just a function that returns the section vnode.

zaceno commented 6 years ago

It's one of those things that's less confusing if you're not using JSX

mietennet commented 6 years ago

ok, thanks again!

great work, guys