Closed 0kku closed 1 year ago
@0kku coming from a react background, this approach seems nice and I guess it feels cleaner, and I’d enjoy writing components this way, but in my opinion, the thing that makes me love destiny is how native it is, everything nowadays are just polyfills and ‘fake native implementations’, a component not being a class and not being able to extend a html element does quite the opposite, it removed the native aspect of it and possibly feels like ‘magic’
I’m torn, but would be curious to hear you thoughts on the above
@0kku coming from a react background, this approach seems nice and I guess it feels cleaner, and I’d enjoy writing components this way, but in my opinion, the thing that makes me love destiny is how native it is, everything nowadays are just polyfills and ‘fake native implementations’, a component not being a class and not being able to extend a html element does quite the opposite, it removed the native aspect of it and possibly feels like ‘magic’
I’m torn, but would be curious to hear you thoughts on the above
Just to be clear: the component would still extend HTMLElement after instantiation, but wouldn't be doing so until after the component has been passed to the template. The intention of the idea was for it to convert the function into a class that extends HTMLElement under the hood. However, I do see your concerns regardless. Also, this conversion would be a non-zero amount of work, so technically it would have slightly more overhead as well.
By the way, something like this would already work for things that don't require lifecycle hooks, since all these things are nothing but JS values:
import { html } from "destiny";
function myTemplate (defaultName: string) {
const who = reactive(defaultName);
return html`
<label>What's your name? <input type="text" value=${who} /></label>
<p>
Hello, ${who}!
</p>
`;
}
function anotherTemplate () {
return html`
<h1>Demo</h1>
${myTemplate("visitor")}
`;
}
document.body.append(anotherTemplate().content);
Yeah fair enough, I do see the functional components being nicer in every way, plus I guess it means you pass in values (like above) as opposed to using custom attributes
I’m warming towards functional components now :) imo
Closed as infeasible and too magical (the bad kind).
Gotten a few requests to support functional components, and after some deliberation, I think it might be possible to do that and it might improve developer ergonomics. Class-style components were the obvious choice because that's what needs to be used to write native Web Components, but I think it's possible to write a functional wrapper for the native Web Components. My primary concern is that I wouldn't want to create confusion by allowing two different ways of writing components, so if this new way was to be adopted, I would likely want to discontinue support for class components.
I think the example from the readme could look something like this:
Each of the web component life cycles would get their own similarly named function exported by the library. Calling these functions outside a functional component would throw. They would not need to have the same limitations as React's hooks: the function's body is only executed once (during element construction), so calling these lifecycle methods conditionally would be fine. Calling these lifecycle methods registers them as callbacks for the respective lifecycle events on the component. The components would need to have a PascalCase name so the template preparser can tell them apart from callback props. The components would still be converted to native Web Components under the hood: the imported lifecycle hooks would be used to convert these functional components into classes for registration.
Unlike class components, these functional components would not extend
HTMLElement
(obviously), which means that they could not be used by any methods that expect an element constructor as input, such ascustomElements.define()
, and would need to be registered by a method provided by the library if one wanted to register them. And since they wouldn't be classes, you also couldn't useinstanceof
on them and you couldn't extend components. I find these limitations to be unimportant, but I'm open to counterarguments.