Skip to content
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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Kelketek
Copy link
Contributor

(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

Copy link
Collaborator

@theengineear theengineear left a 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.
Copy link
Collaborator

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).

Copy link
Contributor Author

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.

Copy link
Collaborator

@theengineear theengineear left a 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.

Copy link
Collaborator

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'.

Copy link
Contributor Author

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!

@Kelketek Kelketek force-pushed the fox/complex-data-passing-docs branch from c665734 to 86916d3 Compare October 19, 2024 20:07
@Kelketek Kelketek force-pushed the fox/complex-data-passing-docs branch from 86916d3 to 4ea09b3 Compare October 19, 2024 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants