Repository navigation
Replies: 4 comments 6 replies
|
You're free to use https://github.com/orenelbaum/babel-plugin-solid-undestructure if that is an issue for you. |
|
There are tradeoffs in "fixing" it. I'm not a fan of those tradeoffs. Mostly that it modifies what your code is doing. It makes everything implicitly reactive. It's not just destructuring either. This is true of any sort of early access. Reversing that actually changes how code operates. Ultimately you still need to be aware of this quality of reactivity. Same concern in MobX or Vue etc. Props are only one-way reactivity enters your file. Unless we could build the perfect abstraction that works across files there will be gaps and unexpected behaviors when you try to hide this. I'm very much of the opinion that a simple model with a simple predictable execution trumps some convenient abstraction that needs to melt away anyway. Things like that babel plugin are great when migrating React code bases etc, and for people who are really sensitive to this sort of syntax thing. But it doesn't change the nature of the thing and in Solid we generally prefer transparency where possible. |
|
Let's start with what defines a "component". In Solid, components are basically just "functions" that can return any value, in the contrary belief that it returns a JSX Element. Guessing which are "components" are definitely tricky to analyze and are probably just recognizable through the human eyes, as these things require contextual analysis. That's the challenge for how the "compiler" would try and fix destructuring, because it needs to know if the function is indeed a component or not. There has been quite some solutions, one being https://github.com/orenelbaum/babel-plugin-solid-undestructure, the other being https://github.com/LXSMNSYC/babel-plugin-solid-labels/blob/main/docs/ctf.md#destructure But, there can be a workaround. In theory, there can be a Babel implementation that allows us to provide a HOC that can "define a component" const Comp = defineComponent(({ message }) => (
<h1>{message}</h1>
));This way, we can analyze immediately which functions are definitely components, and then allow things like destructuring to be fixed during compile-time. |
|
I wonder whether it's worth providing a helper for the common case of wanting to just destructure all props, so you can do: type MyProps = { foo: boolean, bar: string, f: (n: number) => void }
const MyComponent: Component<MyProps> = (props) => {
const { foo, bar, f } = propFns(props)
// work with props; access/call with foo(), bar() or f(123)
}I bodged something together to do this in a typed way: type ReturnTy<Props> = {
[k in keyof Props]:
Props[k] extends Function
? Props[k]
: () => Props[k]
}
export function propFns<Props extends Object>(props: Props): ReturnTy<Props> {
let out = {} as any
for (const p in props) {
if (typeof props[p] === "function") {
// If the prop is a function, leave it be (same args and all)
out[p] = props[p]
} else {
// If the prop is not a function, wrap it in one; it's probably a getter
// and we need it to be lazy.
out[p] = () => props[p]
}
}
return out
}I haven't put much thought into it; perhaps there are edge cases it doesn't deal with? But it's a little more concise than using |
Uh oh!
There was an error while loading. Please reload this page.
The current way you have to handle component props is still a little awkward.
But it gets worse when you have to use splitProps & mergeProps.
Why don't we use the compiler to allow normal destructuring of props and let the compiler change your code to use splitProps & mergeProps.
This will give people no excuse to switch to solidjs :P
All reactions