Table of Contents
The count
variable is fully local, and does not cause "global state bloat". The local state is preserved per session, so would vanish on refresh, but this is perfect for loading
, isDropdownOpen
, and these kind of variables.
Important to call emit('render')
in such a "closure component".
function Counter() {
let count = 0
return (state, emit) => {
const handleClick = () => {
count++
emit('render')
}
return html`
<div>
<div>${count}</div>
<button onclick=${handleClick}>
Click me
</button>
</div>
`
}
}
// Rendering the view
${state.cache(Counter, 'counter')(state, emit)}
Closure variables can be harder to access as they are not in the state
variable. But, because they are cached by the state.cache
function that is defined as
function renderComponent (Component, id) {
assert.equal(typeof Component, 'function', 'choo.state.cache: Component should be type function')
var args = []
for (var i = 0, len = arguments.length; i < len; i++) {
args.push(arguments[i])
}
return cache.render.apply(cache, args)
}
the values that are assigned to the function before you return the view, are cached inside Choo's cache as well. So then, we can mutate the closure variables as following:
function MyToggleComponent() {
let isOpen = false
const view = (state, emit) => {
return html`
<div>
${isOpen
? html`<div>i am open!</div>`
: html`<div>i am closed.</div>`}
</div>
`
}
view.toggle = () => {
isOpen = !isOpen
}
return view
}
// Trigger somewhere else, the `toggle` function
state.cache(MyToggleComponent, 'MyToggleComponent1').toggle()
Callbacks are a good pattern to execute some code after an emitter event has finished.
// In the component
const handleClick = () => {
emit('some-event', () => {
console.log('this will call after the event finished!')
})
}
// In the store
emitter.on('some-event', (cb: (success: boolean) => void) => {
let success = false
try {
// Do something
// ...
success = true
} catch {
// On error
// ...
} finally {
cb(success)
}
})
If you have a function that takes state, emit
as parameters, and if you have the emitter
then you need to pass the emit
as emitter.emit.bind(emitter)
.