{"action":"closed","issue":{"url":"https://api.github.com/repos/lhorie/mithril.js/issues/757","labels_url":"https://api.github.com/repos/lhorie/mithril.js/issues/757/labels{/name}","comments_url":"https://api.github.com/repos/lhorie/mithril.js/issues/757/comments","events_url":"https://api.github.com/repos/lhorie/mithril.js/issues/757/events","html_url":"https://github.com/lhorie/mithril.js/issues/757","id":99335361,"number":757,"title":"Claim: m.component is fragile, suggestion for fix","user":{"login":"ralphbecket","id":1720448,"avatar_url":"https://avatars.githubusercontent.com/u/1720448?v=3","gravatar_id":"","url":"https://api.github.com/users/ralphbecket","html_url":"https://github.com/ralphbecket","followers_url":"https://api.github.com/users/ralphbecket/followers","following_url":"https://api.github.com/users/ralphbecket/following{/other_user}","gists_url":"https://api.github.com/users/ralphbecket/gists{/gist_id}","starred_url":"https://api.github.com/users/ralphbecket/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ralphbecket/subscriptions","organizations_url":"https://api.github.com/users/ralphbecket/orgs","repos_url":"https://api.github.com/users/ralphbecket/repos","events_url":"https://api.github.com/users/ralphbecket/events{/privacy}","received_events_url":"https://api.github.com/users/ralphbecket/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":15,"created_at":"2015-08-06T01:53:04Z","updated_at":"2015-12-21T00:17:46Z","closed_at":"2015-12-21T00:17:46Z","body":"I've been experimenting with `m.component` and I think it's too fragile to use (this is a spin-off of a discussion started at https://groups.google.com/forum/#!topic/mithriljs/poLZ9u2yXwk ).\r\n\r\nHere's my understanding of how `m.component(cmpnt, args)` works when `cmpnt` supplies a `controller` constructor:\r\n- the first time the component instance is rendered in a view, `m.component` will call `cmpnt.controller` to create a controller instance and cache the result;\r\n- on subsequent renderings, **provided** the component instance is in the same place in the vDOM *or* has the same vDOM parent and has been provided with a sibling-unique `key` attribute, then `m.component` will call `cmpnt.view` with the cached controller instance, **otherwise** `m.component` assumes this is a new instance of the component and will construct a new controller instance for it as above;\r\n- this means the lifetime of a component controller instance is strongly dependent on its context in the vDOM.\r\n\r\nI claim that this context dependence is a Very Bad Thing.\r\n\r\nHere is an example http://jsfiddle.net/ralphbecket/y4qgh6e8/3/ where the context of a pair of components is randomly changed by a level of nesting.  Clicking on one of the buttons, you will observe its counter resetting at random as `m.component` behaves as just described.  This is clearly not good and I think the fundamental problem is that Mithril's rendering engine should *not* be responsible for managing component controller lifetimes.\r\n\r\nI have an alternative approach here, http://jsfiddle.net/ralphbecket/y4qgh6e8/6/ .  The code is, if anything, shorter and clearer.  I claim it is morally equivalent to the `{ controller: ..., view: ... }` scheme, but with the strongly desirable context independence.\r\n\r\nI'd go a step further than this: instead of having to return `{ view: function () { ... } }` objects, could Mithril not be extended to also recognise plain function objects in views?  That would remove another layer of unneccessary decoration.\r\n"}}