-
-
Notifications
You must be signed in to change notification settings - Fork 103
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
Support for Roact-like/Class-based components #265
Comments
But Fusion doesn't really have a "render" stage, and "mounting" sounds like a bad practice that goes against the principles of Fusion, components should instead be directly placed into Children. Really, wouldn't you just be making the same code, but in two separate functions for no real reason? Furthermore complicating the library by adding an unnecessary "Component" class |
And it doesn't need one! init and render could be ran once when the component is created (as with regular functional components)
There's no real "mounting" part here though? In the proposal I suggested that components should just return the rendered instance on creation. Also, what do you mean by "components should instead be directly placed into Children"?
Unless there's some hidden feature in VSCode that I'm not aware of, with a class-based component you could just minimize the init function if it gets too big, and instead focus on the actual UI code, something you can't really get with functional components. I guess it's also just syntax sugar. |
I don't really think this is necessary. From what I can gather, this is pretty much just creating an object then calling two methods on it right away, rather than providing some new expansion of what components can do. This is easily achievable in user code and does mean Fusion would impart a relatively significant opinion on user code without a strong motivation or value-add, which I'd like to avoid. I'm more interested in use cases where you want to separate the existence of a component from the process of building its instances. What I mean by this is, for example, wanting to know what components exist in your UI so you can do custom layout, then build those instances with the placement from that layout. This is a use case I'm more actively interested in, and already have been playing around with prototypes of. The idea here is that, instead of directly building instances, constructing a component would immediately construct and return a small, simple table, with a field storing the property table you passed in and a field referencing a table of methods shared between all components of that type. Luau's type annotation system could then be used to define certain 'traits' that can be implemented, similar to Rust. The types define standard methods for performing actions such as building instances, calculating natural layout sizes, or querying for capabilities like input processing. The method tables can then implement methods from as many traits as required. From there, users of components could then call into methods from that method table, and pass in the property table from the component, and you end up with a pretty lightweight semi-OOP component system. I think this extension of components is better motivated and retains a good level of flexibility for users. We will probably need to revise terminology if this ever gets implemented, but it seems like it could be a genuine value-add and a good idea to standardise. This may also help efforts in #263 because it explicitly decouples components from any sort of backend - it's entirely feasible you could share components across Luau environments by simply defining different traits on them. You could even render the same component in different ways within the same environment. |
On reflection and after some discussion in the OSS Discord, this seems like it starts to escape the scope of what's relevant for most Fusion codebases, so I think this sort of feature probably best belongs in an external library to target those users for whom it's relevant. |
Currently, functional components get pretty messy when you start adding a lot of functionality (ex. listening for a humanoid's health property to update an internal health value, etc)
I propose a
Component
classIt would be created the same-way as regular functional components and would return the rendered instance, as to be consistent with functional components
Alternatively, could be created in the same way as Roact, via the New function
There's a library that already does this but has a couple differences, but it'd still be nice to have a native implementation.
The text was updated successfully, but these errors were encountered: