Skip to content

Commit c8e4789

Browse files
committed
Pass children to hydration root constructor
I already made this change for the concurrent root API in #23309. This does the same thing for the legacy API. Doesn't change any behavior, but I will use this in the next steps.
1 parent 581f0c4 commit c8e4789

File tree

11 files changed

+99
-56
lines changed

11 files changed

+99
-56
lines changed

packages/react-art/src/ReactART.js

-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ class Surface extends React.Component {
6969
this._mountNode = createContainer(
7070
this._surface,
7171
LegacyRoot,
72-
false,
7372
null,
7473
false,
7574
false,

packages/react-dom/src/__tests__/ReactDOMRoot-test.js

+9
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,15 @@ describe('ReactDOMRoot', () => {
253253
);
254254
});
255255

256+
it('callback passed to legacy hydrate() API', () => {
257+
container.innerHTML = '<div>Hi</div>';
258+
ReactDOM.hydrate(<div>Hi</div>, container, () => {
259+
Scheduler.unstable_yieldValue('callback');
260+
});
261+
expect(container.textContent).toEqual('Hi');
262+
expect(Scheduler).toHaveYielded(['callback']);
263+
});
264+
256265
it('warns when unmounting with legacy API (no previous content)', () => {
257266
const root = ReactDOMClient.createRoot(container);
258267
root.render(<div>Hi</div>);

packages/react-dom/src/client/ReactDOMLegacy.js

+79-40
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727

2828
import {
2929
createContainer,
30+
createHydrationContainer,
3031
findHostInstanceWithNoPortals,
3132
updateContainer,
3233
flushSync,
@@ -109,34 +110,81 @@ function noopOnRecoverableError() {
109110

110111
function legacyCreateRootFromDOMContainer(
111112
container: Container,
112-
forceHydrate: boolean,
113+
initialChildren: ReactNodeList,
114+
parentComponent: ?React$Component<any, any>,
115+
callback: ?Function,
116+
isHydrationContainer: boolean,
113117
): FiberRoot {
114-
// First clear any existing content.
115-
if (!forceHydrate) {
118+
if (isHydrationContainer) {
119+
if (typeof callback === 'function') {
120+
const originalCallback = callback;
121+
callback = function() {
122+
const instance = getPublicRootInstance(root);
123+
originalCallback.call(instance);
124+
};
125+
}
126+
127+
const root = createHydrationContainer(
128+
initialChildren,
129+
callback,
130+
container,
131+
LegacyRoot,
132+
null, // hydrationCallbacks
133+
false, // isStrictMode
134+
false, // concurrentUpdatesByDefaultOverride,
135+
'', // identifierPrefix
136+
noopOnRecoverableError,
137+
// TODO(luna) Support hydration later
138+
null,
139+
);
140+
container._reactRootContainer = root;
141+
markContainerAsRoot(root.current, container);
142+
143+
const rootContainerElement =
144+
container.nodeType === COMMENT_NODE ? container.parentNode : container;
145+
listenToAllSupportedEvents(rootContainerElement);
146+
147+
flushSync();
148+
return root;
149+
} else {
150+
// First clear any existing content.
116151
let rootSibling;
117152
while ((rootSibling = container.lastChild)) {
118153
container.removeChild(rootSibling);
119154
}
120-
}
121155

122-
const root = createContainer(
123-
container,
124-
LegacyRoot,
125-
forceHydrate,
126-
null, // hydrationCallbacks
127-
false, // isStrictMode
128-
false, // concurrentUpdatesByDefaultOverride,
129-
'', // identifierPrefix
130-
noopOnRecoverableError, // onRecoverableError
131-
null, // transitionCallbacks
132-
);
133-
markContainerAsRoot(root.current, container);
156+
if (typeof callback === 'function') {
157+
const originalCallback = callback;
158+
callback = function() {
159+
const instance = getPublicRootInstance(root);
160+
originalCallback.call(instance);
161+
};
162+
}
163+
164+
const root = createContainer(
165+
container,
166+
LegacyRoot,
167+
null, // hydrationCallbacks
168+
false, // isStrictMode
169+
false, // concurrentUpdatesByDefaultOverride,
170+
'', // identifierPrefix
171+
noopOnRecoverableError, // onRecoverableError
172+
null, // transitionCallbacks
173+
);
174+
container._reactRootContainer = root;
175+
markContainerAsRoot(root.current, container);
176+
177+
const rootContainerElement =
178+
container.nodeType === COMMENT_NODE ? container.parentNode : container;
179+
listenToAllSupportedEvents(rootContainerElement);
134180

135-
const rootContainerElement =
136-
container.nodeType === COMMENT_NODE ? container.parentNode : container;
137-
listenToAllSupportedEvents(rootContainerElement);
181+
// Initial mount should not be batched.
182+
flushSync(() => {
183+
updateContainer(initialChildren, root, parentComponent, callback);
184+
});
138185

139-
return root;
186+
return root;
187+
}
140188
}
141189

142190
function warnOnInvalidCallback(callback: mixed, callerName: string): void {
@@ -164,39 +212,30 @@ function legacyRenderSubtreeIntoContainer(
164212
warnOnInvalidCallback(callback === undefined ? null : callback, 'render');
165213
}
166214

167-
let root = container._reactRootContainer;
168-
let fiberRoot: FiberRoot;
169-
if (!root) {
215+
const maybeRoot = container._reactRootContainer;
216+
let root: FiberRoot;
217+
if (!maybeRoot) {
170218
// Initial mount
171-
root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
219+
root = legacyCreateRootFromDOMContainer(
172220
container,
221+
children,
222+
parentComponent,
223+
callback,
173224
forceHydrate,
174225
);
175-
fiberRoot = root;
176-
if (typeof callback === 'function') {
177-
const originalCallback = callback;
178-
callback = function() {
179-
const instance = getPublicRootInstance(fiberRoot);
180-
originalCallback.call(instance);
181-
};
182-
}
183-
// Initial mount should not be batched.
184-
flushSync(() => {
185-
updateContainer(children, fiberRoot, parentComponent, callback);
186-
});
187226
} else {
188-
fiberRoot = root;
227+
root = maybeRoot;
189228
if (typeof callback === 'function') {
190229
const originalCallback = callback;
191230
callback = function() {
192-
const instance = getPublicRootInstance(fiberRoot);
231+
const instance = getPublicRootInstance(root);
193232
originalCallback.call(instance);
194233
};
195234
}
196235
// Update
197-
updateContainer(children, fiberRoot, parentComponent, callback);
236+
updateContainer(children, root, parentComponent, callback);
198237
}
199-
return getPublicRootInstance(fiberRoot);
238+
return getPublicRootInstance(root);
200239
}
201240

202241
export function findDOMNode(

packages/react-dom/src/client/ReactDOMRoot.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ export function createRoot(
225225
const root = createContainer(
226226
container,
227227
ConcurrentRoot,
228-
false,
229228
null,
230229
isStrictMode,
231230
concurrentUpdatesByDefaultOverride,
@@ -302,6 +301,7 @@ export function hydrateRoot(
302301

303302
const root = createHydrationContainer(
304303
initialChildren,
304+
null,
305305
container,
306306
ConcurrentRoot,
307307
hydrationCallbacks,

packages/react-native-renderer/src/ReactFabric.js

-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ function render(
215215
root = createContainer(
216216
containerTag,
217217
concurrentRoot ? ConcurrentRoot : LegacyRoot,
218-
false,
219218
null,
220219
false,
221220
null,

packages/react-native-renderer/src/ReactNativeRenderer.js

-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ function render(
211211
root = createContainer(
212212
containerTag,
213213
LegacyRoot,
214-
false,
215214
null,
216215
false,
217216
null,

packages/react-noop-renderer/src/createReactNoop.js

-3
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
974974
root = NoopRenderer.createContainer(
975975
container,
976976
tag,
977-
false,
978977
null,
979978
null,
980979
false,
@@ -996,7 +995,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
996995
const fiberRoot = NoopRenderer.createContainer(
997996
container,
998997
ConcurrentRoot,
999-
false,
1000998
null,
1001999
null,
10021000
false,
@@ -1029,7 +1027,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
10291027
const fiberRoot = NoopRenderer.createContainer(
10301028
container,
10311029
LegacyRoot,
1032-
false,
10331030
null,
10341031
null,
10351032
false,

packages/react-reconciler/src/ReactFiberReconciler.new.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -245,16 +245,14 @@ function findHostInstanceWithWarning(
245245
export function createContainer(
246246
containerInfo: Container,
247247
tag: RootTag,
248-
// TODO: We can remove hydration-specific stuff from createContainer once
249-
// we delete legacy mode. The new root API uses createHydrationContainer.
250-
hydrate: boolean,
251248
hydrationCallbacks: null | SuspenseHydrationCallbacks,
252249
isStrictMode: boolean,
253250
concurrentUpdatesByDefaultOverride: null | boolean,
254251
identifierPrefix: string,
255252
onRecoverableError: (error: mixed) => void,
256253
transitionCallbacks: null | TransitionTracingCallbacks,
257254
): OpaqueRoot {
255+
const hydrate = false;
258256
return createFiberRoot(
259257
containerInfo,
260258
tag,
@@ -270,6 +268,8 @@ export function createContainer(
270268

271269
export function createHydrationContainer(
272270
initialChildren: ReactNodeList,
271+
// TODO: Remove `callback` when we delete legacy mode.
272+
callback: ?Function,
273273
containerInfo: Container,
274274
tag: RootTag,
275275
hydrationCallbacks: null | SuspenseHydrationCallbacks,
@@ -305,6 +305,8 @@ export function createHydrationContainer(
305305
// Caution: React DevTools currently depends on this property
306306
// being called "element".
307307
update.payload = {element: initialChildren};
308+
update.callback =
309+
callback !== undefined && callback !== null ? callback : null;
308310
enqueueUpdate(current, update, lane);
309311
scheduleInitialHydrationOnRoot(root, lane, eventTime);
310312

packages/react-reconciler/src/ReactFiberReconciler.old.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -245,16 +245,14 @@ function findHostInstanceWithWarning(
245245
export function createContainer(
246246
containerInfo: Container,
247247
tag: RootTag,
248-
// TODO: We can remove hydration-specific stuff from createContainer once
249-
// we delete legacy mode. The new root API uses createHydrationContainer.
250-
hydrate: boolean,
251248
hydrationCallbacks: null | SuspenseHydrationCallbacks,
252249
isStrictMode: boolean,
253250
concurrentUpdatesByDefaultOverride: null | boolean,
254251
identifierPrefix: string,
255252
onRecoverableError: (error: mixed) => void,
256253
transitionCallbacks: null | TransitionTracingCallbacks,
257254
): OpaqueRoot {
255+
const hydrate = false;
258256
return createFiberRoot(
259257
containerInfo,
260258
tag,
@@ -270,6 +268,8 @@ export function createContainer(
270268

271269
export function createHydrationContainer(
272270
initialChildren: ReactNodeList,
271+
// TODO: Remove `callback` when we delete legacy mode.
272+
callback: ?Function,
273273
containerInfo: Container,
274274
tag: RootTag,
275275
hydrationCallbacks: null | SuspenseHydrationCallbacks,
@@ -305,6 +305,8 @@ export function createHydrationContainer(
305305
// Caution: React DevTools currently depends on this property
306306
// being called "element".
307307
update.payload = {element: initialChildren};
308+
update.callback =
309+
callback !== undefined && callback !== null ? callback : null;
308310
enqueueUpdate(current, update, lane);
309311
scheduleInitialHydrationOnRoot(root, lane, eventTime);
310312

packages/react-reconciler/src/__tests__/ReactFiberHostContext-test.internal.js

-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ describe('ReactFiberHostContext', () => {
7272
const container = Renderer.createContainer(
7373
/* root: */ null,
7474
ConcurrentRoot,
75-
false,
7675
null,
7776
false,
7877
'',
@@ -136,7 +135,6 @@ describe('ReactFiberHostContext', () => {
136135
const container = Renderer.createContainer(
137136
rootContext,
138137
ConcurrentRoot,
139-
false,
140138
null,
141139
false,
142140
'',

packages/react-test-renderer/src/ReactTestRenderer.js

-1
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,6 @@ function create(element: React$Element<any>, options: TestRendererOptions) {
473473
let root: FiberRoot | null = createContainer(
474474
container,
475475
isConcurrent ? ConcurrentRoot : LegacyRoot,
476-
false,
477476
null,
478477
isStrictMode,
479478
concurrentUpdatesByDefault,

0 commit comments

Comments
 (0)