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

fix(ssr): make child props immutable #4779

Merged
merged 6 commits into from
Nov 7, 2024
Merged

Conversation

nolanlawson
Copy link
Collaborator

@nolanlawson nolanlawson commented Nov 4, 2024

Details

This fixes the parent-child-read-only-prop by making props read-only when passed from the parent to the child.

Long-term, we can debate if this is worth it or not – it probably adds a perf overhead, but it is technically consistent with the current engine.

I also added a test to ensure this works correctly for props-that-kinda-look-like-attributes (e.g. title/spellcheck).

Does this pull request introduce a breaking change?

  • 😮‍💨 No, it does not introduce a breaking change.

Does this pull request introduce an observable change?

  • 🤞 No, it does not introduce an observable change.

Gus WI

W-17150218

@nolanlawson nolanlawson requested a review from a team as a code owner November 4, 2024 23:34
Comment on lines 17 to 28
for (let i = 0; i < obj.length; i++) {
res[i] = cloneAndDeepFreeze(obj[i]);
}
freeze(res);
return res;
} else if (!isNull(obj) && isObject(obj)) {
const res = create(null);
for (const [key, value] of entries(obj as any)) {
(res as any)[key] = cloneAndDeepFreeze(value);
}
freeze(res);
return res;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting strategy, going for a classic for loop for one but a for...of w/ destructuring for the other.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I wasn't really going for consistency. I figure we will have to adjust this anyway because I imagine someone is relying on weird differences between forEach/for loops for hole-y arrays anyway. But I can make it a plain loop in both for now.

packages/@lwc/ssr-runtime/src/clone-and-deep-freeze.ts Outdated Show resolved Hide resolved
packages/@lwc/ssr-runtime/src/clone-and-deep-freeze.ts Outdated Show resolved Hide resolved
// that they are immutable. This is one of the normal guarantees of both engine-dom and engine-server that we want to
// emulate in ssr-runtime. The goal here is that a child cannot mutate the props of its parent and thus affect
// the parent's rendering, which would lead to bidirectional reactivity and mischief.
export function cloneAndDeepFreeze(obj: any): any {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could something like immer handle this? (Do we have that in runtime or just compiler?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think immer is just in the compiler.

Long-term, we may delete this function entirely. I'm sure it adds perf overhead, and it's arguably not useful since you will likely get an error on the client side if you rely on children mutating their parents' props. Maybe it makes sense in dev-only, or pure-SSR-(no hydration)-only.

nolanlawson and others added 5 commits November 7, 2024 09:21
Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com>
Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com>
@nolanlawson nolanlawson enabled auto-merge (squash) November 7, 2024 17:31
@nolanlawson nolanlawson merged commit a85b192 into master Nov 7, 2024
11 checks passed
@nolanlawson nolanlawson deleted the nolan/immutable-props branch November 7, 2024 17:41
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