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

Unify ReactFiberCurrentOwner and ReactCurrentFiber #29038

Merged
merged 2 commits into from
May 23, 2024

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented May 10, 2024

We previously had two slightly different concepts for "current fiber".

There's the "owner" which is set inside of class components in prod if string refs are enabled, and sometimes inside function components in DEV but not other contexts.

Then we have the "current fiber" which is only set in DEV for various warnings but is enabled in a bunch of contexts.

This unifies them into a single "current fiber".

The concept of string refs shouldn't really exist so this should really be a DEV only concept. In the meantime, this sets the current fiber inside class render only in prod, however, in DEV it's now enabled in more contexts which can affect the string refs. That was already the case that a string ref in a Function component was only connecting to the owner in prod. Any string ref associated with any non-class won't work regardless so that's not an issue. The practical change here is that an element with a string ref created inside a life-cycle associated with a class will work in DEV but not in prod. Since we need the current fiber to be available in more contexts in DEV for the debugging purposes. That wouldn't affect any old code since it would have a broken ref anyway. New code shouldn't use string refs anyway.

The other implication is that "owner" doesn't necessarily mean "rendering" since we need the "owner" to track other debug information like stacks - in other contexts like useEffect, life cycles, etc. Internally we have a separate isRendering flag that actually means we're rendering but even that is a very overloaded concept. So anything that uses "owner" to imply rendering might be wrong with this change.

This is a first step to a larger refactor for tracking current rendering information.

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels May 10, 2024
// Reset this to null before calling lifecycles
if (__DEV__ || !disableStringRefs) {
setCurrentOwner(null);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We weren't really initializing this to anything and we were always cleaning it up so I don't think this has been necessary for a while. However, since the life cycles also set the current debug fiber we get the resetting for free regardless - at least in DEV.

@react-sizebot
Copy link

react-sizebot commented May 10, 2024

Comparing: 55dd0b1...599e50f

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.66 kB 6.66 kB +0.05% 1.82 kB 1.82 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 495.71 kB 495.71 kB = 88.78 kB 88.75 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.67 kB 6.67 kB +0.05% 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 500.51 kB 500.51 kB = 89.47 kB 89.43 kB
facebook-www/ReactDOM-prod.classic.js +0.07% 592.86 kB 593.27 kB +0.08% 104.28 kB 104.37 kB
facebook-www/ReactDOM-prod.modern.js +0.10% 569.08 kB 569.65 kB +0.08% 100.69 kB 100.77 kB
test_utils/ReactAllWarnings.js Deleted 64.35 kB 0.00 kB Deleted 16.05 kB 0.00 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-experimental/react-reconciler/cjs/react-reconciler-reflection.development.js +0.71% 18.57 kB 18.70 kB +0.90% 5.31 kB 5.36 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler-reflection.development.js +0.71% 18.57 kB 18.70 kB +0.90% 5.31 kB 5.36 kB
oss-stable/react-reconciler/cjs/react-reconciler-reflection.development.js +0.71% 18.57 kB 18.70 kB +0.90% 5.31 kB 5.36 kB
facebook-www/ReactTestUtils-dev.classic.js +0.23% 44.68 kB 44.78 kB +0.32% 12.78 kB 12.82 kB
facebook-www/ReactTestUtils-dev.modern.js +0.23% 44.68 kB 44.78 kB +0.32% 12.78 kB 12.82 kB
test_utils/ReactAllWarnings.js Deleted 64.35 kB 0.00 kB Deleted 16.05 kB 0.00 kB

Generated by 🚫 dangerJS against 599e50f

@@ -2486,7 +2486,7 @@ export function commitMutationEffects(

setCurrentDebugFiberInDEV(finishedWork);
commitMutationEffectsOnFiber(finishedWork, root, committedLanes);
setCurrentDebugFiberInDEV(finishedWork);
resetCurrentDebugFiberInDEV();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was an bug before and the layout effects just reset to previous so it left the last mutation fiber as the debug fiber after commit.

@sebmarkbage sebmarkbage force-pushed the currentowner branch 3 times, most recently from 32f2bab to 0812517 Compare May 10, 2024 04:29
@@ -2586,14 +2586,14 @@ describe('TreeListContext', () => {
utils.act(() => TestRenderer.create(<Contexts />));
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This used to log an react-test-renderer is deprecated error which shouldn't be counted towards the rendered errors. It was previously incorrectly associated to the previous tree because the "current fiber" wasn't reset after the commit phase of the previous render.

That's why the snapshots below have one less error counted.

Copy link

vercel bot commented May 21, 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 May 21, 2024 4:29pm

packages/react-reconciler/src/ReactFiberAsyncDispatcher.js Outdated Show resolved Hide resolved
// @gate !disableStringRefs
it('throws an error', async () => {
// @gate !disableStringRefs && !__DEV__
it('throws an error in prod', async () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

What does it do in dev now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We use the same fields for dev and prod just to temporarily support string refs but in DEV it's active for the entire begin / complete phases for debugging purposes. Meaning that it just works in dev because the owner is set up but in prod it's not.

It still has a console.error in DEV so you shouldn't add any new callers as long as the warning actually shows up.

Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>
@sebmarkbage sebmarkbage merged commit 2e3e6a9 into facebook:main May 23, 2024
40 checks passed
github-actions bot pushed a commit that referenced this pull request May 23, 2024
We previously had two slightly different concepts for "current fiber".

There's the "owner" which is set inside of class components in prod if
string refs are enabled, and sometimes inside function components in DEV
but not other contexts.

Then we have the "current fiber" which is only set in DEV for various
warnings but is enabled in a bunch of contexts.

This unifies them into a single "current fiber".

The concept of string refs shouldn't really exist so this should really
be a DEV only concept. In the meantime, this sets the current fiber
inside class render only in prod, however, in DEV it's now enabled in
more contexts which can affect the string refs. That was already the
case that a string ref in a Function component was only connecting to
the owner in prod. Any string ref associated with any non-class won't
work regardless so that's not an issue. The practical change here is
that an element with a string ref created inside a life-cycle associated
with a class will work in DEV but not in prod. Since we need the current
fiber to be available in more contexts in DEV for the debugging
purposes. That wouldn't affect any old code since it would have a broken
ref anyway. New code shouldn't use string refs anyway.

The other implication is that "owner" doesn't necessarily mean
"rendering" since we need the "owner" to track other debug information
like stacks - in other contexts like useEffect, life cycles, etc.
Internally we have a separate `isRendering` flag that actually means
we're rendering but even that is a very overloaded concept. So anything
that uses "owner" to imply rendering might be wrong with this change.

This is a first step to a larger refactor for tracking current rendering
information.

---------

Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>

DiffTrain build for commit 2e3e6a9.
github-actions bot pushed a commit that referenced this pull request May 23, 2024
We previously had two slightly different concepts for "current fiber".

There's the "owner" which is set inside of class components in prod if
string refs are enabled, and sometimes inside function components in DEV
but not other contexts.

Then we have the "current fiber" which is only set in DEV for various
warnings but is enabled in a bunch of contexts.

This unifies them into a single "current fiber".

The concept of string refs shouldn't really exist so this should really
be a DEV only concept. In the meantime, this sets the current fiber
inside class render only in prod, however, in DEV it's now enabled in
more contexts which can affect the string refs. That was already the
case that a string ref in a Function component was only connecting to
the owner in prod. Any string ref associated with any non-class won't
work regardless so that's not an issue. The practical change here is
that an element with a string ref created inside a life-cycle associated
with a class will work in DEV but not in prod. Since we need the current
fiber to be available in more contexts in DEV for the debugging
purposes. That wouldn't affect any old code since it would have a broken
ref anyway. New code shouldn't use string refs anyway.

The other implication is that "owner" doesn't necessarily mean
"rendering" since we need the "owner" to track other debug information
like stacks - in other contexts like useEffect, life cycles, etc.
Internally we have a separate `isRendering` flag that actually means
we're rendering but even that is a very overloaded concept. So anything
that uses "owner" to imply rendering might be wrong with this change.

This is a first step to a larger refactor for tracking current rendering
information.

---------

Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>

DiffTrain build for [2e3e6a9](2e3e6a9)
Copy link
Contributor

@yungsters yungsters left a comment

Choose a reason for hiding this comment

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

Are we missing an isRendering check in findNodeHandle in ReactNativePublicCompat.js, too?

yungsters added a commit that referenced this pull request May 29, 2024
This was missed in #29038 when
unifying the "owner" abstractions, causing `findNodeHandle` to warn even
outside of `render()` invocations.
github-actions bot pushed a commit that referenced this pull request May 29, 2024
This was missed in #29038 when
unifying the "owner" abstractions, causing `findNodeHandle` to warn even
outside of `render()` invocations.

DiffTrain build for commit 3b29ed1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants