Skip to content

Instantly share code, notes, and snippets.

@dwaltrip
Last active May 2, 2017 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwaltrip/3e0b4ad7b0187284a36bcdab674e9a15 to your computer and use it in GitHub Desktop.
Save dwaltrip/3e0b4ad7b0187284a36bcdab674e9a15 to your computer and use it in GitHub Desktop.
Differences in `key` behavior between mithril v0.2.5 and mithril v1
<html lang="en">
<head>
<meta charset="utf-8">
<title>Mixing keyed and non-keyed Vnodes</title>
<!-- <script src="https://unpkg.com/mithril@0.2.5/mithril.js"></script> -->
<script src="https://unpkg.com/mithril@1.1.1/mithril.js"></script>
<style>
body { margin: 10px; }
button { margin-bottom: 10px; }
.item-list { display: flex; flex-direction: column; align-items: flex-start; font-size: 15px; color: #333; }
.item-wrapper { display: flex; align-items: center; padding: 5px 8px; border: 1px solid #555; margin: 3px; }
.item-icon { height: 8px; width: 8px; border-radius: 50%; background: #8da; margin-right: 4px; }
.another-div { display: flex; }
.extra-stuff { font-size: 12px; color: #999; margin-left: 5px; }
</style>
</head>
<body>
<div id='root'></div>
<script>
// var isMithrilV1 = false;
var isMithrilV1 = true;
var Item = {
// The issue only happens if we store `item` on the component instance, and use that in the view
// In Item.view, if we access the passed in attrs/params directly, we won't notice that the component is stale
oninit: function(vnode) { this.item = vnode.attrs.item; },
controller: function(params) { this.item = params.item; },
view: function() {
var instance = (isMithrilV1 ? this : arguments[0]);
return m('.item', instance.item.text);
}
};
function appComponentInit() {
console.log('Currently using ' + (isMithrilV1 ? 'mithril-v1' : 'mithril-v0.2.5'));
this.data = [
{ text: '1st item' },
{ text: 'don\'t mix keyed and non-keyed things' },
{ text: 'foo baz' },
{ text: 'the last item' }
];
this.swapFirstAndLast = ()=> {
this.data = [].concat(
this.data.slice(-1).pop(), // last item
this.data.slice(1, -1), // everything in between
this.data[0] // first item
);
};
}
var App = {
oninit: appComponentInit,
controller: appComponentInit,
view: function() {
var instance = (isMithrilV1 ? this : arguments[0]);
return m('.app', [
m('button', { onclick: instance.swapFirstAndLast }, 'Swap first & last'),
m('.item-list', instance.data.map(item => {
var itemContent = m(Item, { item: item, key: item.text });
return m('.item-wrapper', [
m('.item-icon'),
/* Nested array isn't needed in v0.2.5 */
itemContent
/* Nested array is required to avoid mixing keyed/non-keyed vnodes in v1
otherwise, "swap" button won't work */
// [ itemContent ]
]);
}))
]);
}
};
m.mount(document.getElementById('root'), App);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment