Skip to content

Commit

Permalink
feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
tyao1 committed Nov 17, 2022
1 parent f81256c commit f523f9a
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1786,70 +1786,103 @@ describe('ReactDOMServerSelectiveHydration', () => {
document.body.removeChild(container);
});

describe('it can force hydration in response to', () => {
it('can force hydration in response to sync update', () => {
function Child({text}) {
Scheduler.unstable_yieldValue(`Child ${text}`);
return <span ref={ref => (spanRef = ref)}>{text}</span>;
}
function App({text}) {
Scheduler.unstable_yieldValue(`App ${text}`);
return (
<div>
<Suspense fallback={null}>
<Child text={text} />
</Suspense>
</div>
);
}

let spanRef;
let initialSpan;
let root;
let App;
beforeEach(() => {
function Child({text}) {
Scheduler.unstable_yieldValue(`Child ${text}`);
return <span ref={ref => (spanRef = ref)}>{text}</span>;
}
App = function({text}) {
Scheduler.unstable_yieldValue(`App ${text}`);
return (
<div>
<Suspense fallback={null}>
<Child text={text} />
</Suspense>
</div>
);
};
const finalHTML = ReactDOMServer.renderToString(<App text="A" />);
expect(Scheduler).toHaveYielded(['App A', 'Child A']);
const container = document.createElement('div');
document.body.appendChild(container);
container.innerHTML = finalHTML;
const initialSpan = container.getElementsByTagName('span')[0];
const root = ReactDOMClient.hydrateRoot(container, <App text="A" />);
expect(Scheduler).toFlushUntilNextPaint(['App A']);

const finalHTML = ReactDOMServer.renderToString(<App text="A" />);
expect(Scheduler).toHaveYielded(['App A', 'Child A']);
const container = document.createElement('div');
document.body.appendChild(container);
container.innerHTML = finalHTML;
initialSpan = container.getElementsByTagName('span')[0];
root = ReactDOMClient.hydrateRoot(container, <App text="A" />);
expect(Scheduler).toFlushUntilNextPaint(['App A']);
ReactDOM.flushSync(() => {
root.render(<App text="B" />);
});
expect(Scheduler).toHaveYielded(['App B', 'Child A', 'App B', 'Child B']);
expect(initialSpan).toBe(spanRef);
});

it('sync update', () => {
ReactDOM.flushSync(() => {
root.render(<App text="B" />);
});
expect(Scheduler).toHaveYielded(['App B', 'Child A', 'App B', 'Child B']);
expect(initialSpan).toBe(spanRef);
});
// @gate experimental || www
it('can force hydration in response to continuous update', () => {
function Child({text}) {
Scheduler.unstable_yieldValue(`Child ${text}`);
return <span ref={ref => (spanRef = ref)}>{text}</span>;
}
function App({text}) {
Scheduler.unstable_yieldValue(`App ${text}`);
return (
<div>
<Suspense fallback={null}>
<Child text={text} />
</Suspense>
</div>
);
}

// @gate experimental || www
it('continuous update', () => {
TODO_scheduleContinuousSchedulerTask(() => {
root.render(<App text="B" />);
});
expect(Scheduler).toFlushAndYield([
'App B',
'Child A',
'App B',
'Child B',
]);
expect(initialSpan).toBe(spanRef);
let spanRef;
const finalHTML = ReactDOMServer.renderToString(<App text="A" />);
expect(Scheduler).toHaveYielded(['App A', 'Child A']);
const container = document.createElement('div');
document.body.appendChild(container);
container.innerHTML = finalHTML;
const initialSpan = container.getElementsByTagName('span')[0];
const root = ReactDOMClient.hydrateRoot(container, <App text="A" />);
expect(Scheduler).toFlushUntilNextPaint(['App A']);

TODO_scheduleContinuousSchedulerTask(() => {
root.render(<App text="B" />);
});
expect(Scheduler).toFlushAndYield(['App B', 'Child A', 'App B', 'Child B']);
expect(initialSpan).toBe(spanRef);
});

it('default update', () => {
ReactDOM.unstable_batchedUpdates(() => {
root.render(<App text="B" />);
});
expect(Scheduler).toFlushAndYield([
'App B',
'Child A',
'App B',
'Child B',
]);
expect(initialSpan).toBe(spanRef);
it('can force hydration in response to default update', () => {
function Child({text}) {
Scheduler.unstable_yieldValue(`Child ${text}`);
return <span ref={ref => (spanRef = ref)}>{text}</span>;
}
function App({text}) {
Scheduler.unstable_yieldValue(`App ${text}`);
return (
<div>
<Suspense fallback={null}>
<Child text={text} />
</Suspense>
</div>
);
}

let spanRef;
const finalHTML = ReactDOMServer.renderToString(<App text="A" />);
expect(Scheduler).toHaveYielded(['App A', 'Child A']);
const container = document.createElement('div');
document.body.appendChild(container);
container.innerHTML = finalHTML;
const initialSpan = container.getElementsByTagName('span')[0];
const root = ReactDOMClient.hydrateRoot(container, <App text="A" />);
expect(Scheduler).toFlushUntilNextPaint(['App A']);

ReactDOM.unstable_batchedUpdates(() => {
root.render(<App text="B" />);
});
expect(Scheduler).toFlushAndYield(['App B', 'Child A', 'App B', 'Child B']);
expect(initialSpan).toBe(spanRef);
});
});
9 changes: 2 additions & 7 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ import {
import {
NoLanes,
NoLane,
SyncHydrationLane,
SyncLane,
NoTimestamp,
claimNextTransitionLane,
Expand Down Expand Up @@ -918,8 +917,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
// TODO: Temporary until we confirm this warning is not fired.
if (
existingCallbackNode == null &&
existingCallbackPriority !== SyncLane &&
existingCallbackPriority !== SyncHydrationLane
!includesSyncLane(existingCallbackPriority)
) {
console.error(
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
Expand All @@ -937,10 +935,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {

// Schedule a new callback.
let newCallbackNode;
if (
newCallbackPriority === SyncLane ||
newCallbackPriority === SyncHydrationLane
) {
if (includesSyncLane(newCallbackPriority)) {
// Special case: Sync React callbacks are scheduled on a special
// internal queue
if (root.tag === LegacyRoot) {
Expand Down
9 changes: 2 additions & 7 deletions packages/react-reconciler/src/ReactFiberWorkLoop.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ import {
import {
NoLanes,
NoLane,
SyncHydrationLane,
SyncLane,
NoTimestamp,
claimNextTransitionLane,
Expand Down Expand Up @@ -918,8 +917,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
// TODO: Temporary until we confirm this warning is not fired.
if (
existingCallbackNode == null &&
existingCallbackPriority !== SyncLane &&
existingCallbackPriority !== SyncHydrationLane
!includesSyncLane(existingCallbackPriority)
) {
console.error(
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
Expand All @@ -937,10 +935,7 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {

// Schedule a new callback.
let newCallbackNode;
if (
newCallbackPriority === SyncLane ||
newCallbackPriority === SyncHydrationLane
) {
if (includesSyncLane(newCallbackPriority)) {
// Special case: Sync React callbacks are scheduled on a special
// internal queue
if (root.tag === LegacyRoot) {
Expand Down

0 comments on commit f523f9a

Please sign in to comment.