The following code works as expected: it creates two counter buttons that persist their state and update on clicking:
let Counter = function (vnode) {
let count = 0
return {
view: (vnode) => {
return m("button",
{
onclick: function () {
console.log(count++)
}
}, "Count: " + count)
}
}
}
let Counters = {
view: () => [
m(Counter),
m(Counter),
]
}
m.mount(document.body, Counters)
However, if I define the array of Counter
components in a separate variable and pass that to the Counters
view function, then the view stops updating. The state persists and I can see incrementing count logged to console, but nothing changes on screen. This is the updated code:
let Counter = function (vnode) {
let count = 0
return {
view: (vnode) => {
return m("button",
{
onclick: function () {
console.log(count++)
}
}, "Count: " + count)
}
}
}
let counters =
[
m(Counter),
m(Counter),
]
let Counters = {
view: () => counters
}
m.mount(document.body, Counters)
Why would this be happening? This is a toy example of a more complicated Mithril application that I'm working on, where I would like to arbitrarily sort the array of child components.
I was able to gather useful feedback in the Mithril Gitter chat and will post what I learned below.
The reason the counters in my example were not updating was because they were defined once inside the
counters
array and it was returned subsequently. As the same array is returned every time theview()
function ofCounters
is called,Counters
does not see a need to update as it thinks that the elements it is returning have not changed. Even though theCounter
elements inside the array update, the reference to the array remains the same.One way of handling this is by defining a factory function that would return a new sorted array of
Counter
elements each time theview()
function onCounters
is called. Furthermore, the application state then needs to be kept in a global location and the only parameter passed to eachCounter
is the index of the global counter it is referencing, like so:A working JSFiddle can be found here.