-
-
Notifications
You must be signed in to change notification settings - Fork 937
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
feat: call components with .call
to allow libs to provide class components with static .call
methods
#1260
base: main
Are you sure you want to change the base?
Conversation
…ponents with static `.call` methods Also formatted with prettier, some unformatted code got by in previous commits. Co-authored-by: Fabio Spampinato <[email protected]>
Pull Request Test Coverage Report for Build 3165847540Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
Maybe it can be just class ShowCount {
static call(_, props) {
return new this().template(props)
}
...
} which leads to the same result. Maybe |
I can't build or test locally, I get
Also GitHub actions reports the tests to have passed, but if you take a look, it had a bunch of errors. |
? P | ||
: T extends keyof JSX.IntrinsicElements | ||
? JSX.IntrinsicElements[T] | ||
: Record<string, unknown>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just formatting applied by prettier
| keyof JSX.IntrinsicElements | ||
| Component<any> | ||
| (string & {}); | ||
export type ValidComponent = keyof JSX.IntrinsicElements | Component<any> | (string & {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just formatting applied by prettier
this change may have performance implications, where the common case of "function" has to go
alternatively, the class can be wrapper in a "functional factory". https://playground.solidjs.com/?hash=437964492&version=1.4.1 |
That's interesting that a JS engine doesn't simply optimize away what are essentially identical calls.
What would the code look like? If we use |
I have attached a playground to demonstrate what it looks like practically. |
Performance implications means it needs to be tested, considered, and not a quick merge. |
As I love classes as components I have no idea how I missed this PR 😅 But it seams like the issues stopped being relevant as it can be simply solved by splitting class state from template: class State {
foo = 123
}
export function ShowCount(props) {
const state = new State(props);
return <div>Count is {props.count} and foo is {state.foo}</div>
} the flexibility of current solution is strong enough to cover all possible cases and abstract layers without creating new API and deal with perf choices. It also allows for state / template separation for those against SFC. I agree it could be simplified with some utils but I believe that's a role for external package to come up with things like: import { component } from "solid-class-components"
class State {
foo = 123;
}
export const ShowCountState = component(State, (props) => (
<div>
Count is {props.count} and foo is {this.foo}
</div>
)); Ofc, this would affect performance as well, but it is fully controllable by the user without general cost to all components. |
Also formatted with prettier, some unformatted code got by in previous commits.
Summary
Thanks @fabiospampinato for ideating and ending with this idea.
Calling components as
Comp.call(Comp, props)
allows for classes to be used as components if they have astatic call
method. Existing function components work the same, and this is what a class could look like:How did you test this change?