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

Bug: Effects are run on parents of suspending components #21510

Closed
chriserickson opened this issue May 14, 2021 · 6 comments
Closed

Bug: Effects are run on parents of suspending components #21510

chriserickson opened this issue May 14, 2021 · 6 comments
Labels
Resolution: Duplicate Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@chriserickson
Copy link

chriserickson commented May 14, 2021

With a component hierarchy like:

<Suspense>
  <Parent>
    <Child /> {/*<-- this one suspends */}
  </Parent>
</Suspense>

If the child throws to suspense, neither the parent nor child are in the DOM. However, the parents effects are still run. This breaks classes of layout effects, e.g. measuring text etc.

React version: 17.0.2

Steps To Reproduce

  1. Open code sandbox
  2. Look at console

Link to code example: https://codesandbox.io/s/parent-effects-suspense-m2k4q?file=/src/App.tsx (see the console)

The current behavior

Effects are run on parent component even though it isn't in the DOM

The expected behavior

Effects are not run on the parent component until it is actually mounted

@chriserickson chriserickson added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label May 14, 2021
@chriserickson
Copy link
Author

For context, we ran into this with Relay - a useFragment block suspended sometimes, causing a parent component's layout effects to make incorrect measurements. It is worked around with an intermediate suspense boundary, but that may not be desirable if you want the entire screen to wait to load until the sub-components are able to load.

@eps1lon
Copy link
Collaborator

eps1lon commented May 15, 2021

Thanks for the report.

This is similar to #14536 and #18141

Unfortunately, it is not possible to fix with ReactDOM.render:

My understanding is that this is not possible to fix in the legacy (ReactDOM.render) mode. Sorry. It's a quirk of the legacy mode which we can't fix without introducing other breaking changes. This is solved in Blocking Mode and Concurrent Mode, but they are only available in experimental releases for now.

-- #18141

Note that "Blocking Mode" is no longer availabe in the latest experimental releases.

@gaearon
Copy link
Collaborator

gaearon commented May 15, 2021

Yeah, this is exactly the kind of thing that Concurrent Mode solves. We can't solve it outside of that because it would violate the constraints that non-CM-compatible code assumes.

@gaearon
Copy link
Collaborator

gaearon commented Jun 16, 2021

React 18 alpha with createRoot fixes this.
https://codesandbox.io/s/parent-effects-suspense-forked-t9r2m?file=/src/App.tsx

@chriserickson
Copy link
Author

👍🏻 Thank you!

@gaearon
Copy link
Collaborator

gaearon commented Mar 29, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Duplicate Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

3 participants