Reputation: 3221
Here, i am trying to update the document to contain a number of elements, and i am removing the step by step. I have tried 2 approaches, one which does not involve creating m-objects
, and another one where i create new m-objects
on every m.render()
. I was using the first method in my program, and it didnt work, so i decided to test Mithril and found this behaviour.
This does not work:
e1 = m('i', 'e1');
e2 = m('i', 'e2');
e3 = m('i', 'e3');
m.render(document.body, m('b', [e1, e2, e3]));
// "e1e2e3" appears
m.render(document.body, m('b', [e2, e3]));
// "e2e3" appears
m.render(document.body, m('b', [e3]));
// "e2e3" appears
m.render(document.body, m('b', []));
// "e2e3" appears
Interestingly, if instead i remove items from the end, it works:
e1 = m('i', 'e1');
e2 = m('i', 'e2');
e3 = m('i', 'e3');
m.render(document.body, m('b', [e1, e2, e3]));
// "e1e2e3" appears
m.render(document.body, m('b', [e1, e2]));
// "e1e2" appears
m.render(document.body, m('b', [e1]));
// "e1" appears
m.render(document.body, m('b', []));
// "" appears
And, this method always works (both ways):
m.render(document.body, m('b', [m('i', 'e1'), m('i', 'e2'), m('i', 'e3')]));
// "e1e2e3" appears
m.render(document.body, m('b', [m('i', 'e2'), m('i', 'e3')]));
// "e2e3" appears
m.render(document.body, m('b', [m('i', 'e3')]));
// "e3" appears
m.render(document.body, m('b', []));
// "" appears
I think i could use the last method in my program, but i wanted to know why the original method does not work.
Upvotes: 0
Views: 104
Reputation: 6509
When you are working with lists of data that may change (reorder or add/remove items) it's good practice to set a key
to each component/element that is related to the data it presents.
I am not exactly sure what Mithril does under the hood here, but without the keys it's not able to properly identify which children are being removed every time. (It more often works when removing from the end of the list.)
With proper keys, however, it always works:
var children = [
m('i', {key: 'e1'}, 'e1'),
m('i', {key: 'e2'}, 'e2'),
m('i', {key: 'e3'}, 'e3')
];
function show() {
m.render(document.body, m('b', {onclick: removeFirst}, children));
}
function removeFirst() {
children = children.slice(1);
console.log('children', children);
show();
}
show();
<body>
<script src="https://unpkg.com/mithril/mithril.js"></script>
<script src="index.js"></script>
</body>
Upvotes: 2