-
Notifications
You must be signed in to change notification settings - Fork 12
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
docs: Document re-rendering based on complex data. #191
base: main
Are you sure you want to change the base?
Conversation
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.
Hey @Kelketek! I think my feedback here is that we should advocate for the use of referential updates in integration code (versus advocating for imperative alternatives).
doc/TEMPLATES.md
Outdated
@@ -67,6 +67,20 @@ The following template languages are supported: | |||
* html | |||
* svg | |||
|
|||
### Nested Data and Re-rendering | |||
|
|||
Web components will only trigger a re-render by default **when their properties are replaced**. This means that when using non-primitive data structures as properties, mutating the contents of these structures will not result in the component re-rendering. You must either replace the data structure or manually call the `.render` method. |
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.
My high-level feedback is that the x-element
documentation ought to advocate for consistently leveraging change-by-reference detection patterns.
I.e., rather than say “if you use a compound object, you need to do extra imperative calls when you mutate the data” — we should say “mint new object references versus mutating data in place”.
Object / array spread operators make this pretty straightforward in modern JS. The bet is that the cost (both performance and complexity) is cheaper to simply update object references when binding properties (versus encoding and performing many imperative calls to mutate DOM).
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.
@theengineear I've updated the docs to avoid mentioning the imperative re-rending method, and have made it clear that change-by-reference is recommended.
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.
Sorry to be nit-picky! I think I understand the sentiment that you’re trying to land in here, but I’m just trying to find the right way to help you convey it. I left a counter-proposal for you in a review comment 🤘
### Nested Data and Re-rendering | ||
|
||
Web components will only trigger a re-render by default **when their properties are replaced**. This means that when using non-primitive data structures as properties, mutating the contents of these structures will not result in the component re-rendering. This is by design. When you need to update a nested data structure on a web component, replace the property's value with a newly minted data structure. | ||
|
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.
I think the language around “web components” is still a little too loose — this is more about template engines IMO. Rather than go back-and-forth, how about I just draft up a quick counter-proposal for you? Thoughts?
A note on non-primitive data:
Because DOM manipulation is slow — template engines do their best to avoid it (if a value hasn’t changed, DOM manipulation is skipped). To know if a non-primitive property has changed, a change-by-reference check is performed (versus a change-by-value check). Therefore treat non-primitives as if they’re immutable. I.e., do this: element.property = { ...element.property, foo: 'bar' }
. And don’t do this: element.property.foo = 'bar'
.
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.
@theengineear Thanks-- yes, some of the boundaries are still fuzzy to me since this project is my first use of web components. I was on the fence about writing something on the lines of 'treat non-primitives as though they're immutable', even though I was understanding this to be the implication, because that almost seemed like something that should be discussed in the design philosophy section, but I couldn't think of a way to fit it in there.
I'll think a bit more on whether there's a better way to communicate the expected design patterns this library is hoping to encourage. Although, it might be obvious to people who know they need it.
In any case, I made a couple of small grammatical changes to the suggested replacement, rebased and squashed. Should be ready for you, thanks!
c665734
to
86916d3
Compare
86916d3
to
4ea09b3
Compare
(Re-opened since #190 was forcibly auto-closed by the target merge branch being deleted)
This PR adds documentation on rendering limitations as they pertain to complex data structures. It also makes some minor typographical adjustments found along the way.
cc @theengineear @klebba