domchanger icon indicating copy to clipboard operation
domchanger copied to clipboard

cleanup not called when updating/refreshing

Open kruczy opened this issue 10 years ago • 11 comments

Hey, I have found an issue that cleanup will not be called though a component will be removed from the tree and replaced with a new one (same type but new instance)

please have a look at some sample code: http://jsfiddle.net/BsUDE/9/

In the output it should be 1,2 not 0,2

this can cause leaking of resources (eg if I would setInterval in the component)

kruczy avatar Nov 26 '15 12:11 kruczy

Hey, Found out what's really happening

It will just call update and not create a new instance of inner component

checked what happens if component would change and it cleans the previous one though im my apps case the problem was the name of the component would be the same since I used a wrapper function, see: http://jsfiddle.net/BsUDE/12/

kruczy avatar Nov 26 '15 12:11 kruczy

So the problem is you're swapping out components, but since they have the same ID, it doesn't actually swap them?

creationix avatar Nov 28 '15 00:11 creationix

Yes it would appear so, the reason for this in my case is that I have a wrapper function around my components

Also this will be the same for browsers that don't have function.name even if you don't use a wrapper see: https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/Function/name

probably better way of comparing would be to check if it is the same function using === if I have time ill try to create a pr for this

kruczy avatar Nov 29 '15 17:11 kruczy

Managed to solve it another way, when I'm using my wrapper instead of just wrapping my component factory I wrap the whole array and set the key property to unique id of the view, now everything works perfectly

kruczy avatar Nov 30 '15 14:11 kruczy

Yes, setting the key property will work. That's how I've been doing it. I'm still concerned about the original issues that bit you though.

creationix avatar Nov 30 '15 16:11 creationix

I could solve this with a WeakSet of WeakMap, but that would change the minimim requirements for JavaScript significantly. (The idea is to store a weak list of all seen constructors and give each a unique ID so that they can be serialized to a string for the id algorithm.)

creationix avatar Nov 30 '15 16:11 creationix

The way I am thinking now would be sufficient is something like:

//define this somewhere
var constructorIdProperty = Symbol ? Symbol('domchangerId') : '_domchangerId';
//maybe just '_domchangerId' to allow users to overwrite it?
var viewId = 1;

//get the id or create one (assuming component is the factory function)
var id = component[constructorIdProperty];
if(!id) {
 id = component[constructorIdProperty] = "View" + viewId++;
}

(didn't run this so might not work)

This would allow the property to be hidden and not need more deps

kruczy avatar Dec 01 '15 11:12 kruczy

Ok, so stick a property on the constructor. I suppose that would work, it's just messy to annotate passed in values directly. But as you say, this does work without weakmaps.

creationix avatar Dec 02 '15 03:12 creationix

I don't think it is actually that bad since all browsers except IE have basic Symbol implementation so the value will not clash with anything and will be hidden from the user, though WeakMap would be nicer

only problem that can happen potentially is if someone iterates over properties of the constructor in IE and expects the value not to be there, though this can also be fixed by defining a non-enumerable property

kruczy avatar Dec 02 '15 14:12 kruczy

Sounds good, want to send a PR?

creationix avatar Dec 02 '15 15:12 creationix

sure, won't have time today, might do tomorrow though

kruczy avatar Dec 02 '15 17:12 kruczy