-
Notifications
You must be signed in to change notification settings - Fork 47.8k
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
[refactor] Add element type for Activity #32499
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,7 @@ import { | |
TracingMarkerComponent, | ||
Throw, | ||
ViewTransitionComponent, | ||
ActivityComponent, | ||
} from './ReactWorkTags'; | ||
import {OffscreenVisible} from './ReactFiberActivityComponent'; | ||
import {getComponentNameFromOwner} from 'react-reconciler/src/getComponentNameFromFiber'; | ||
|
@@ -108,6 +109,7 @@ import { | |
REACT_TRACING_MARKER_TYPE, | ||
REACT_ELEMENT_TYPE, | ||
REACT_VIEW_TRANSITION_TYPE, | ||
REACT_ACTIVITY_TYPE, | ||
} from 'shared/ReactSymbols'; | ||
import {TransitionTracingMarker} from './ReactFiberTracingMarkerComponent'; | ||
import { | ||
|
@@ -595,6 +597,8 @@ export function createFiberFromTypeAndProps( | |
} | ||
} else { | ||
getTag: switch (type) { | ||
case REACT_ACTIVITY_TYPE: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like we should be able to delete the Offscreen case? |
||
return createFiberFromActivity(pendingProps, mode, lanes, key); | ||
case REACT_FRAGMENT_TYPE: | ||
return createFiberFromFragment(pendingProps.children, mode, lanes, key); | ||
case REACT_STRICT_MODE_TYPE: | ||
|
@@ -874,6 +878,17 @@ export function createFiberFromOffscreen( | |
fiber.stateNode = primaryChildInstance; | ||
return fiber; | ||
} | ||
export function createFiberFromActivity( | ||
pendingProps: OffscreenProps, | ||
mode: TypeOfMode, | ||
lanes: Lanes, | ||
key: null | string, | ||
): Fiber { | ||
const fiber = createFiber(ActivityComponent, pendingProps, key, mode); | ||
fiber.elementType = REACT_ACTIVITY_TYPE; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not actually right. This was wrong for In the case of In fact, it looks like we get this wrong for all these built-ins so wrapping them would yield the wrong reconciliation. So it's an existing bug that we need to fix separately. |
||
fiber.lanes = lanes; | ||
return fiber; | ||
} | ||
|
||
export function createFiberFromViewTransition( | ||
pendingProps: ViewTransitionProps, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,7 @@ import { | |
TracingMarkerComponent, | ||
Throw, | ||
ViewTransitionComponent, | ||
ActivityComponent, | ||
} from './ReactWorkTags'; | ||
import { | ||
NoFlags, | ||
|
@@ -867,6 +868,46 @@ function deferHiddenOffscreenComponent( | |
// fork the function. | ||
const updateLegacyHiddenComponent = updateOffscreenComponent; | ||
|
||
function updateActivityComponent( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs a close review, I have no idea what I'm doing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea this sounds about right. |
||
current: null | Fiber, | ||
workInProgress: Fiber, | ||
renderLanes: Lanes, | ||
) { | ||
const nextProps = workInProgress.pendingProps; | ||
const nextChildren = nextProps.children; | ||
const nextMode = nextProps.mode; | ||
const mode = workInProgress.mode; | ||
const offscreenChildProps: OffscreenProps = { | ||
mode: nextMode, | ||
children: nextChildren, | ||
}; | ||
|
||
if (current === null) { | ||
const primaryChildFragment = mountWorkInProgressOffscreenFiber( | ||
offscreenChildProps, | ||
mode, | ||
renderLanes, | ||
); | ||
primaryChildFragment.ref = workInProgress.ref; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sebmarkbage currently I'm just forwarding the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. |
||
workInProgress.child = primaryChildFragment; | ||
primaryChildFragment.return = workInProgress; | ||
|
||
return primaryChildFragment; | ||
} else { | ||
const currentChild: Fiber = (current.child: any); | ||
|
||
const primaryChildFragment = updateWorkInProgressOffscreenFiber( | ||
currentChild, | ||
offscreenChildProps, | ||
); | ||
|
||
primaryChildFragment.ref = workInProgress.ref; | ||
workInProgress.child = primaryChildFragment; | ||
primaryChildFragment.return = workInProgress; | ||
return primaryChildFragment; | ||
} | ||
} | ||
|
||
function updateCacheComponent( | ||
current: Fiber | null, | ||
workInProgress: Fiber, | ||
|
@@ -4024,6 +4065,9 @@ function beginWork( | |
} | ||
break; | ||
} | ||
case ActivityComponent: { | ||
return updateActivityComponent(current, workInProgress, renderLanes); | ||
} | ||
case OffscreenComponent: { | ||
return updateOffscreenComponent(current, workInProgress, renderLanes); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -154,6 +154,7 @@ import { | |
REACT_OFFSCREEN_TYPE, | ||
REACT_POSTPONE_TYPE, | ||
REACT_VIEW_TRANSITION_TYPE, | ||
REACT_ACTIVITY_TYPE, | ||
} from 'shared/ReactSymbols'; | ||
import ReactSharedInternals from 'shared/ReactSharedInternals'; | ||
import { | ||
|
@@ -2261,6 +2262,7 @@ function renderElement( | |
task.keyPath = prevKeyPath; | ||
return; | ||
} | ||
case REACT_ACTIVITY_TYPE: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sebmarkbage this might not be correct - to match the client it should render an Offscreen element, but I'm not sure how to do that in Fizz. Without that, I think this might cause a hydration error if it's rendered in mode There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Offscreen is an implementation detail of Fiber and it will never be noticeable in the HTML so it can't hydrate. Basically Fizz doesn't need to know about the concept of Offscreen. It doesn't need the same type of code sharing between Suspense and Activity that Fiber needs to manage the complexity. So it can be just forked paths. In other words, you can just drop |
||
case REACT_OFFSCREEN_TYPE: { | ||
renderOffscreen(request, task, keyPath, props); | ||
return; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ export const REACT_MEMO_TYPE: symbol = Symbol.for('react.memo'); | |
export const REACT_LAZY_TYPE: symbol = Symbol.for('react.lazy'); | ||
export const REACT_SCOPE_TYPE: symbol = Symbol.for('react.scope'); | ||
export const REACT_OFFSCREEN_TYPE: symbol = Symbol.for('react.offscreen'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this still used anywhere or can this be deleted now? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically the idea is that React internally only refers to Offscreen using the tag. It should never have to look at |
||
export const REACT_ACTIVITY_TYPE: symbol = Symbol.for('react.activity'); | ||
export const REACT_LEGACY_HIDDEN_TYPE: symbol = Symbol.for( | ||
'react.legacy_hidden', | ||
); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is actually a good example for why we need this to be a separate wrapper. Because this should not be ignored. It should be visible in React DevTools because it's not an internal implementation detail but actually something the user renders.
The reason OffscreenComponent was hidden was because it's an internal of Suspense and it would be very noisy to show it everywhere but the Activity one we actually want to show.
So this should actually go into one of the other paths (and be filterable as a "type" in the filters).
This could be done as a follow up though.