-
-
Notifications
You must be signed in to change notification settings - Fork 113
Declarative hyperHTML.Component #202
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
Conversation
6fb33b4
to
6dbb7dc
Compare
Hi @WebReflection , I like this implementation. Some thoughts:
class UserInfo extends hyperHTML.Component {
onclick(e) {
if (this.props.editUserProfile) this.props.editUserProfile();
}
render(props) { return this.html`
<div onclick=${this} class="user-info">
${Avatar.for(this).render(props)}
<div class="user-info-name">
${props.name}
</div>
</div>`;
}
}
class UserInfo extends hyperHTML.Component {
onclick(e) {
// how to access the element ref? At the moment I have to write a lot of onconnected callback to save the element inside class.
this.ref.className = "after-click";
// how to use the nested component instance?
this.avartar.changeStyle();
}
render(props) { return this.html`
<div onclick=${this} class="user-info">
${Avatar.for(this).render(props)}
<div class="user-info-name">
${props.name}
</div>
</div>`;
}
}
|
Hi @liming, thanks for coming back with questions. To start with, after thinking a lot about this, I've realized Accordingly, while I am sure having a basic
|
This pattern is quite close to what I'm building now. It's quite useful for building complex component. class MyComp extends hyper.Component {
constructor(props = {name: 'anonymous'}) {
this.update(props);
}
update(props) {
this.props = props;
this.setState({active: !!props.active}, false);
return this.render();
}
render() {
return this.html`<p>I am ${this.props.name}</p>`;
}
} It should be fine not to include the pattern into Component as long as hyperHTML can provide good samples to follow. About get the reference of nested component, I think it should be a must-have feature for Component. It can be something like this: // declare the Child component:
Child.for(this, 1)
Child.for(this, 2)
// find the Child component:
const children = Child.search(this) // return 2 children
const child = Child.search(this, 1) // return 1 child How cool it is! Borrow Symbol.search() concept. |
well, About
Moreover, if you declare children you can just assign them and skip the this.children = [
new Child,
new Child
]; Above snippet is way cleaner on the constructor, as example, and gives you the ability to render children like this: this.html`<ul>${this.children}</ul>`; where if you want to update them this.html`<ul>${list.map((data, i) => this.children[i].update(data))}</ul>`; Last, but not least, you can pass a |
Yes there are so many patterns to make things work, but they are not easy to use, especially for developers playing with hyperHTML only a few weeks. And we have to write same patrerns in each Component again and again to achieve same thing. It eventually will result in either someone rebuild a new Component based on hyper Component, or choose other Component based solution. I guess the problem is you want to keep it as small as possible, because the Component stays INSIDE hyperHTML. Maybe you should separate it out, so we can contribute as much as possible. This way you can build a full ecosystem revolving around this Component, instead of only limited features to make it just work. |
uhm ... unexpected answer ... I'm not making it just work, I'm telling you what are the limits and issues. I don't have control of the scope around hyperHTML, but I can simplify composition and what I've proposed seems already simpler than what you had to write 'till now. Specially with the JSX transformation to hyperHTML prototype, the However, having a I was hoping for some more hint on how to improve, and by no mean I want to block components development, indeed same way I've created the hyperHTML is a primitive to drive layouts and nothing else, really, it has its strengths but also its limits. As example, tell me how would I reference child nodes to an owner which doesn't exist at DOM creation. It's not as trivial as it looks, and picking the right pattern is key, IMO. |
6dbb7dc
to
66b703f
Compare
It is clear at this point basic
hyper.Component
is too basic and not so friendly when it comes to compose the layout.Few developers already mentioned this, and I've been thinking about a way to get closer to JSX simplicity.
Through HTML: why not
One possible solution was to somehow give components a way to define themselves.
The idea behind was to parse the HTML and somehow transform all
<MyComponent />
into some abstraction but the cons overreach the pros:hyperHTML
would like to still promote standard practices as much as possible.Current Proposal
Using @liming idea, I've played with a declarative implementation that moves the main logic to the render (or any other defined method, really).
Instead of passing
props
like values through attributes, we can passprops
directly to the render.To prevent harakiri situations with the state, declarative components won't render automatically while non declarative components can decide to not render now on demand (unfortunately these shipped already so I don't want to break backward compatibility).
Examples
Following a couple of examples, starting with the @liming Menu and MenuItem case:
The following one is a basic React example reproduced through components:
I am quite happy with the approach/result but I'd love to hear from users their thoughts before it lands.
Thank You!