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

Assign resolved outlined props to element object (and not only tuple) #30528

Merged
merged 3 commits into from
Jul 30, 2024

Conversation

unstubbable
Copy link
Contributor

When an element is used multiple times as shown in #30526, its props might be deduped. When resolving the reference to the deduped props, we were only updating the React element tuple, which at this point has already been parsed into a React element object, using null as placeholder props. Therefore, updating the element tuple doesn't help much, and we need to make sure that the element object's props are updated as well.

This is a similar fix as #28669, see the code lines above, and thus feels similarly hacky. Maybe there's a better way to fix this? @eps1lon was mentioning offline that solving this TODO would probably fix it properly, since we wouldn't need to deal with stale tuples then. But that's a way heavier lift.

Copy link

vercel bot commented Jul 30, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-compiler-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 30, 2024 6:05pm

@react-sizebot
Copy link

react-sizebot commented Jul 30, 2024

Comparing: ab7c166...265d8dc

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.68 kB 6.68 kB = 1.83 kB 1.83 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 501.29 kB 501.29 kB = 89.95 kB 89.95 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.69 kB 6.69 kB = 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 508.41 kB 508.41 kB = 91.12 kB 91.12 kB
facebook-www/ReactDOM-prod.classic.js = 596.31 kB 596.31 kB = 105.76 kB 105.76 kB
facebook-www/ReactDOM-prod.modern.js = 572.61 kB 572.61 kB = 101.96 kB 101.96 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable-rc/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.js +0.61% 46.35 kB 46.63 kB +0.46% 9.50 kB 9.55 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.js +0.61% 46.35 kB 46.63 kB +0.46% 9.50 kB 9.55 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.js +0.61% 46.35 kB 46.63 kB +0.46% 9.50 kB 9.55 kB
oss-stable-rc/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.js +0.61% 76.64 kB 77.11 kB +0.72% 16.30 kB 16.42 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.js +0.61% 76.64 kB 77.11 kB +0.72% 16.30 kB 16.42 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.js +0.61% 76.64 kB 77.11 kB +0.72% 16.30 kB 16.42 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.js +0.61% 46.85 kB 47.13 kB +0.48% 9.57 kB 9.62 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.js +0.60% 77.38 kB 77.84 kB +0.74% 16.41 kB 16.53 kB
oss-stable-rc/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.js +0.59% 47.96 kB 48.24 kB +0.45% 9.87 kB 9.91 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.js +0.59% 47.96 kB 48.24 kB +0.45% 9.87 kB 9.91 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.js +0.59% 47.96 kB 48.24 kB +0.45% 9.87 kB 9.91 kB
oss-stable-rc/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.js +0.59% 48.29 kB 48.58 kB +0.44% 9.96 kB 10.00 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.js +0.59% 48.29 kB 48.58 kB +0.44% 9.96 kB 10.00 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.js +0.59% 48.29 kB 48.58 kB +0.44% 9.96 kB 10.00 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.js +0.59% 48.46 kB 48.74 kB +0.49% 9.94 kB 9.99 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.js +0.58% 48.79 kB 49.08 kB +0.48% 10.03 kB 10.08 kB
oss-stable-rc/react-client/cjs/react-client-flight.production.js +0.57% 52.23 kB 52.53 kB +0.50% 9.68 kB 9.73 kB
oss-stable-semver/react-client/cjs/react-client-flight.production.js +0.57% 52.23 kB 52.53 kB +0.50% 9.68 kB 9.73 kB
oss-stable/react-client/cjs/react-client-flight.production.js +0.57% 52.23 kB 52.53 kB +0.50% 9.68 kB 9.73 kB
oss-experimental/react-client/cjs/react-client-flight.production.js +0.57% 52.63 kB 52.93 kB +0.44% 9.73 kB 9.77 kB
oss-stable-rc/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.js +0.56% 50.55 kB 50.84 kB +0.44% 10.52 kB 10.57 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.js +0.56% 50.55 kB 50.84 kB +0.44% 10.52 kB 10.57 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.js +0.56% 50.55 kB 50.84 kB +0.44% 10.52 kB 10.57 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.js +0.56% 51.05 kB 51.34 kB +0.42% 10.59 kB 10.63 kB
oss-stable-rc/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.production.js +0.55% 51.81 kB 52.09 kB +0.43% 10.80 kB 10.84 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.production.js +0.55% 51.81 kB 52.09 kB +0.43% 10.80 kB 10.84 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.production.js +0.55% 51.81 kB 52.09 kB +0.43% 10.80 kB 10.84 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.production.js +0.54% 52.31 kB 52.59 kB +0.41% 10.87 kB 10.91 kB
oss-stable-rc/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.js +0.54% 52.51 kB 52.79 kB +0.44% 10.95 kB 11.00 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.js +0.54% 52.51 kB 52.79 kB +0.44% 10.95 kB 11.00 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.js +0.54% 52.51 kB 52.79 kB +0.44% 10.95 kB 11.00 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.js +0.54% 53.01 kB 53.29 kB +0.44% 11.02 kB 11.07 kB
oss-stable-rc/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.js +0.53% 53.65 kB 53.93 kB +0.42% 11.18 kB 11.23 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.js +0.53% 53.65 kB 53.93 kB +0.42% 11.18 kB 11.23 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.js +0.53% 53.65 kB 53.93 kB +0.42% 11.18 kB 11.23 kB
oss-stable-rc/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.js +0.53% 53.66 kB 53.95 kB +0.42% 11.17 kB 11.21 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.js +0.53% 53.66 kB 53.95 kB +0.42% 11.17 kB 11.21 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.js +0.53% 53.66 kB 53.95 kB +0.42% 11.17 kB 11.21 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.js +0.52% 54.15 kB 54.44 kB +0.44% 11.25 kB 11.29 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.js +0.52% 54.16 kB 54.45 kB +0.44% 11.23 kB 11.28 kB
oss-stable-rc/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.js +0.51% 55.40 kB 55.68 kB +0.42% 11.30 kB 11.35 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.js +0.51% 55.40 kB 55.68 kB +0.42% 11.30 kB 11.35 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.js +0.51% 55.40 kB 55.68 kB +0.42% 11.30 kB 11.35 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.js +0.51% 55.88 kB 56.17 kB +0.39% 11.38 kB 11.42 kB
oss-stable-rc/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.js +0.51% 56.09 kB 56.37 kB +0.42% 11.47 kB 11.51 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.js +0.51% 56.09 kB 56.37 kB +0.42% 11.47 kB 11.51 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.js +0.51% 56.09 kB 56.37 kB +0.42% 11.47 kB 11.51 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.js +0.50% 56.57 kB 56.85 kB +0.42% 11.54 kB 11.59 kB
oss-stable-rc/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.45% 104.77 kB 105.24 kB +0.54% 23.55 kB 23.67 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.45% 104.77 kB 105.24 kB +0.54% 23.55 kB 23.67 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.45% 104.77 kB 105.24 kB +0.54% 23.55 kB 23.67 kB
oss-stable-rc/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.42% 74.50 kB 74.81 kB +0.27% 14.03 kB 14.06 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.42% 74.50 kB 74.81 kB +0.27% 14.03 kB 14.06 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.42% 74.50 kB 74.81 kB +0.27% 14.03 kB 14.06 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.42% 112.71 kB 113.17 kB +0.54% 25.33 kB 25.47 kB
oss-stable-rc/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.41% 76.35 kB 76.67 kB +0.28% 14.42 kB 14.46 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.41% 76.35 kB 76.67 kB +0.28% 14.42 kB 14.46 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.41% 76.35 kB 76.67 kB +0.28% 14.42 kB 14.46 kB
oss-stable-rc/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.41% 76.81 kB 77.12 kB +0.28% 14.54 kB 14.58 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.41% 76.81 kB 77.12 kB +0.28% 14.54 kB 14.58 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.41% 76.81 kB 77.12 kB +0.28% 14.54 kB 14.58 kB
oss-stable-rc/react-client/cjs/react-client-flight.development.js +0.40% 78.04 kB 78.36 kB +0.26% 14.30 kB 14.33 kB
oss-stable-semver/react-client/cjs/react-client-flight.development.js +0.40% 78.04 kB 78.36 kB +0.26% 14.30 kB 14.33 kB
oss-stable/react-client/cjs/react-client-flight.development.js +0.40% 78.04 kB 78.36 kB +0.26% 14.30 kB 14.33 kB
oss-stable-rc/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.39% 79.59 kB 79.90 kB +0.31% 15.03 kB 15.07 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.39% 79.59 kB 79.90 kB +0.31% 15.03 kB 15.07 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.39% 79.59 kB 79.90 kB +0.31% 15.03 kB 15.07 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.39% 79.88 kB 80.19 kB +0.29% 15.00 kB 15.04 kB
oss-stable-rc/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +0.39% 81.00 kB 81.32 kB +0.30% 15.34 kB 15.38 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +0.39% 81.00 kB 81.32 kB +0.30% 15.34 kB 15.38 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +0.39% 81.00 kB 81.32 kB +0.30% 15.34 kB 15.38 kB
oss-stable-rc/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.38% 81.81 kB 82.13 kB +0.25% 15.51 kB 15.55 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.38% 81.81 kB 82.13 kB +0.25% 15.51 kB 15.55 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.38% 81.81 kB 82.13 kB +0.25% 15.51 kB 15.55 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.38% 81.84 kB 82.15 kB +0.27% 15.41 kB 15.46 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.38% 82.30 kB 82.61 kB +0.26% 15.52 kB 15.56 kB
oss-stable-rc/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.38% 83.18 kB 83.49 kB +0.25% 15.80 kB 15.84 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.38% 83.18 kB 83.49 kB +0.25% 15.80 kB 15.84 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.38% 83.18 kB 83.49 kB +0.25% 15.80 kB 15.84 kB
oss-stable-rc/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.38% 83.19 kB 83.51 kB +0.25% 15.78 kB 15.82 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.38% 83.19 kB 83.51 kB +0.25% 15.78 kB 15.82 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.38% 83.19 kB 83.51 kB +0.25% 15.78 kB 15.82 kB
oss-experimental/react-client/cjs/react-client-flight.development.js +0.37% 83.49 kB 83.81 kB +0.30% 15.28 kB 15.33 kB
oss-stable-rc/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +0.37% 84.92 kB 85.23 kB +0.29% 15.86 kB 15.91 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +0.37% 84.92 kB 85.23 kB +0.29% 15.86 kB 15.91 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +0.37% 84.92 kB 85.23 kB +0.29% 15.86 kB 15.91 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.37% 84.93 kB 85.24 kB +0.27% 16.05 kB 16.10 kB
oss-stable-rc/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.36% 85.71 kB 86.02 kB +0.25% 16.04 kB 16.08 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.36% 85.71 kB 86.02 kB +0.25% 16.04 kB 16.08 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.36% 85.71 kB 86.02 kB +0.25% 16.04 kB 16.08 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +0.36% 86.34 kB 86.65 kB +0.29% 16.37 kB 16.41 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.36% 87.15 kB 87.46 kB +0.27% 16.53 kB 16.58 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.35% 88.52 kB 88.83 kB +0.27% 16.79 kB 16.84 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.35% 88.53 kB 88.84 kB +0.26% 16.77 kB 16.82 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +0.35% 90.33 kB 90.64 kB +0.28% 16.89 kB 16.94 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.34% 91.13 kB 91.44 kB +0.27% 17.06 kB 17.11 kB

Generated by 🚫 dangerJS against 1d38832

When an element is used multiple times as shown in facebook#30526, its props
might be deduped. When resolving the reference to the deduped props, we
were only updating the React element tuple, which at this point has
already been parsed into a React element object, using `null` as
placeholder props. Therefore, updating the element tuple doesn't help
much, and we need to make sure that the element object's props are
updated as well.

This is a similar fix as facebook#28669, see the code lines above, and thus
feels similarly hacky. Maybe there's a better way to fix this? @eps1lon
was mentioning offline that solving [this
TODO](https://github.com/facebook/react/blob/33e54fa252b9dbe7553ef42a2287c3dbbd4f035d/packages/react-client/src/ReactFlightClient.js#L1327)
would probably fix it properly, since we wouldn't need to deal with
stale tuples then. But that's a way heavier lift.
) {
handler.value.props = parentObject[key];
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

I knew about this issue but I was basically ignoring it because I was expecting us to always dedupe parent JSX object itself instead but this is a case where that doesn't happen. I wonder if there's more with keys and stuff.

Copy link
Collaborator

@eps1lon eps1lon left a comment

Choose a reason for hiding this comment

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

Fix makes sense to me though I agree that it looks a bit fragile. I'll also make sure it fixes the case we were seeing in vercel.com

typeof handler.value === 'object' &&
handler.value !== null &&
handler.value.$$typeof === REACT_ELEMENT_TYPE &&
handler.value.props === null
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are there cases where the props are already resolved i.e. handler.value.props !== null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure. At least there's no test failing without the check. But since we don't have 100% test coverage in the flight client, I wanted to be on the safe side.

Copy link
Collaborator

Choose a reason for hiding this comment

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

When we do this at the root it's actually a feature because we don't know that the empty '' key means that it's at the root. The null check implies that we're at the root because we couldn't be waiting for anything else until the root is done.

In this case, this check is kind of unnecessary. If you trust that we do the rest of the logic correct so you don't need it, and if we don't do it right it'll probably break anyway.

So I think just remove this since you need to be able to do this for every other key anyway (key, props, owner, stack...). It's just unnecessary to check all of them.

typeof handler.value === 'object' &&
handler.value !== null &&
handler.value.$$typeof === REACT_ELEMENT_TYPE &&
handler.value.props === null
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we put the placeholder that we return from waitForReference into a dedicated variable to make it clear what we're referencing here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deferring to @sebmarkbage here. If we do, we should probably consider the null return value in getOutlinedModel as well.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's tricky because the placeholder can effect on the hidden class. E.g. undefined is not good for this reason (but also it deletes the property in JSON.parse). Symbols could maybe have similar optimizations to small numbers so feels sketchy too. Most likely this will end up being an object or object-like like string. Maybe an empty object but then that might imply that the next object should have same hidden class.

However, as I mentioned above we also don't need this in this case so I think null is fine.

// parsed element object (i.e. handler.value).
if (
parentObject[0] === REACT_ELEMENT_TYPE &&
key === '3' &&
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this the first time we're doing this kind of check? Maybe we should put these indices into variables to make it clearer what we're referencing here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are at least two more cases:

if (key === '' && handler.value === null) {

if (initializingHandler !== null && key === '0') {

Also deferring the answer to @sebmarkbage.

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 in this case, this problem is not limited to this particular slot though. It can happen to any key. Like the "type" and the "owner" (in DEV only) too.

So I think we probably should handle every key that an element can have and map it to its property name.

Copy link
Collaborator

@sebmarkbage sebmarkbage left a comment

Choose a reason for hiding this comment

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

Nit: Handle all the other fields on element too.

Any one of them could be a reference to a client reference that has any value so it applies to any type.

@eps1lon eps1lon merged commit 3208e73 into facebook:main Jul 30, 2024
185 checks passed
@unstubbable unstubbable deleted the sebbie/flight-fragment-deduping branch July 30, 2024 19:48
unstubbable added a commit to unstubbable/react that referenced this pull request Jul 31, 2024
This is a follow-up from facebook#30528 to not only handle props (the critical
change), but also the owner and stack of a referenced element.

Handling stacks here is rather academic because the Flight Server
currently does not deduplicate owner stacks. And if they are really
identical, we should probably just dedupe the whole element.
unstubbable added a commit to unstubbable/react that referenced this pull request Jul 31, 2024
This is a follow-up from facebook#30528 to not only handle props (the critical
change), but also the owner and stack of a referenced element.

Handling stacks here is rather academic because the Flight Server
currently does not deduplicate owner stacks. And if they are really
identical, we should probably just dedupe the whole element.
unstubbable added a commit to unstubbable/react that referenced this pull request Jul 31, 2024
This playwright test is using the Flight Fixture to demonstrate the
Flight Reply equivalent of the scenario that was fixed in facebook#30528 for the
Flight Client.

It's basically an advanced case of what was outlined in facebook#28564,
returning a client component from a server action that is used in
`useActionState`. In addition, the client component uses another element
twice, which leads to the element's props being deduped. Resolving those
references needs to be handled specifically, both in the Flight Client
(done in facebook#30528), as well as in the temporary references of the Flight
Reply Client (and possibly Flight Reply Server?).

The test should probably be converted into a unit test, e.g. in
`packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js`
or
`packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReply-test.js`.
@mobeigi
Copy link

mobeigi commented Sep 22, 2024

Howdy @unstubbable and @sebmarkbage ,

I believe this change has introduced a regression that leads to this bug: vercel/next.js#69545
I incorrectly created the bug on the next.js repo but I believe its actually a React bug.

Basically an unhandled runtime error when 2 or more distinct SVGR SVG components are rendered in the same server component.

I'm not familiar with this code, could you advice if this seems to be the cause?

🙇

unstubbable added a commit to unstubbable/react that referenced this pull request Sep 23, 2024
This is a follow-up from facebook#30528 to not only handle props (the critical
change), but also the owner and stack of a referenced element.

Handling stacks here is rather academic because the Flight Server
currently does not deduplicate owner stacks. And if they are really
identical, we should probably just dedupe the whole element.
@unstubbable
Copy link
Contributor Author

@mobeigi Thanks for reporting this. The issue will be fixed with #30549.

sebmarkbage pushed a commit that referenced this pull request Sep 24, 2024
This is a follow-up from #30528 to not only handle props (the critical
change), but also the owner ~and stack~ of a referenced element.

~Handling stacks here is rather academic because the Flight Server
currently does not deduplicate owner stacks. And if they are really
identical, we should probably just dedupe the whole element.~ EDIT:
Removed from the PR.

Handling owner objects on the other hand is an actual requirement as
reported in vercel/next.js#69545. This problem
only affects the stable release channel, as the absence of owner stacks
allows for the specific kind of shared owner deduping as demonstrated in
the unit test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants