Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explanation of subtree patching algorithm #1

Open
jayrbolton opened this issue Apr 24, 2017 · 6 comments
Open

Explanation of subtree patching algorithm #1

jayrbolton opened this issue Apr 24, 2017 · 6 comments
Labels

Comments

@jayrbolton
Copy link

Hey @tinchoz49, I'm interested in your code here and am trying to grok how your subtree patching works. Would you be willing to describe a little bit how it works?

@tinchoz49
Copy link
Owner

Hi @jayrbolton, I'm very glad to know about your interest in the snabbmitt code. Right now I'm busy traveling to home but tomorrow I can write you a better description of how it works.

@tinchoz49
Copy link
Owner

tinchoz49 commented Apr 26, 2017

So, the idea started when I tested the patch function in a subtree of the snabbdom vtree and it works!

/**
  * lastVtree is the last version of our entire virtual dom patched in the DOM
  * so each vnode has their `elm` property set
  *
**/

// we can do this
const subtree = lastVtree.children[0];
patch(subtree, newVnode); 

Since every element in the vtree is a regular vnode, it's understandable that the patch function can work in each of these nodes.
The only required is that a subtree patching can only work if the prevVnode was already patched on the DOM.
A particular problem that I had was that when you do a subtree patching you create an entire new vnode object and you lost the reference of your parent in the vtree. The solution was always kept the old object and copy the properties of the new object in the old one. https://github.com/tinchoz49/snabbmitt/blob/master/lib/component/hook.js#L27

When I had this part finished I started with the stateful component part.

In snabbmitt, a stateful component is a closure function where you can define a view and a store.
The renderer is connected to an internal event emitter that each component creates on the instance process.
But also, the store use that event emitter as a connection between your view and the state. I mean, each update in your state it has to pass through this event emitter.

I don't know if this description clarifies your questions or tell me if you need help for a specific part.

@jayrbolton
Copy link
Author

Many thanks @tinchoz49 , this explanation is helpful for me to understand better. I'll be playing with the code!

@tinchoz49
Copy link
Owner

new ideas are welcome too! 😄

@jayrbolton
Copy link
Author

Hi @tinchoz49, I'm returning to this after a very long delay ... I still like the idea here a lot.

One question I have is how you can aggregate data from child components. For example, in your example directory, how would you display average values for each list section, and then a final average for all values on the page?

You would need to access the state of each child from the parent on every child update, add them together, and display that within the parent. Maybe you've thought about or played with this use case? I think in real-world apps this type of aggregation is very common.

@jayrbolton
Copy link
Author

So I was thinking of adding a global bus that could solve the above issue. With a global bus, you could access any arbitrary state and trigger arbitrary events from one component to another without having to worry about parameters. When you initialize a component, you could set its namespace for the global bus. From any other component, you could listen to and fire events to any other component if you have its namespace.

I'm going to play with idea (in a very large and complex app) and see if it works well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants