Skip to content
This repository has been archived by the owner on Dec 13, 2023. It is now read-only.

Introduce branching #128

Closed
idiomic opened this issue Jul 6, 2018 · 4 comments
Closed

Introduce branching #128

idiomic opened this issue Jul 6, 2018 · 4 comments

Comments

@idiomic
Copy link
Contributor

idiomic commented Jul 6, 2018

Right now the Roact tree is tightly bound and restricted by the Roblox tree. Each stateful or functional component must evaluate to one or no Roblox instances in the reconciler. This means that for a stateful or functional component that requires multiple Roblox instances to function properly, the stateful or functional component must create a root primitive element to parent the primitive elements it needs to. This often results in more primitive elements (whose mounting, reconciling, and unmount is prohibitively expensive) then are needed.

The problem with returning multiple elements is that it is difficult to implement from a language perspective. I assume this is why it has not been implemented. In Lua, a function which can return multiple values needs to be handled differently by the caller. Either the caller needs to know how many values are being returned in advance (not plausible in our case) or the caller needs to create a table (prohibitively expensive again because it creates a table every call).

I propose that the render method of the component returning multiple elements be the entity responsible for creating a table to hold the multiple values, only when needed. This would be done by returning an element as normal, whose component type is a branch component. This branch component would be mounted as a child of its parent and then mount its children. When reconciled, it would reconcile each of its children. When unmounted, it would unmount each of its children.

It is essentially transparent and lightweight compared to its current reliance upon an external tree (the Roblox tree right now) to store children information.

@AmaranthineCodices
Copy link
Contributor

This seems like a duplicate of #7

@idiomic
Copy link
Contributor Author

idiomic commented Jul 6, 2018

@AmaranthineCodices, I checked out #7. This issue calls for the same functionality but suggests a different implementation. Perhaps we should relocate this issue as a comment in #7?

The main advantage of leaving the fragment or branch component inside the resulting tree is that another table doesn't have to be created every reconcile to store visited children, including visited children by visiting a fragment/branch component. It also isn't dependent upon all children being reconciled before any children can be unmounted.

@idiomic
Copy link
Contributor Author

idiomic commented Jul 7, 2018

An additional implementation note that wasn't included before: this would remove the need for primitive components to handle having multiple children, only the branch component would handle multiple children. When createElement is used to add children to a component, it sets the _child property of the element to a branch component with the proper children. This change does break code that uses children. (Is that part of the reason why the "" was put before it?)

@LPGhatguy
Copy link
Contributor

The easiest way to implement this is by creating a custom iterator and relaxing children to be a table of children OR a single child. I think that's the route we'll be going, and doing that in #7.

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

No branches or pull requests

3 participants