Skip to content

Commit

Permalink
Don't warn about concurrently rendering contexts if we finished rende…
Browse files Browse the repository at this point in the history
…ring (#22797)

Closes #22796
  • Loading branch information
eps1lon authored Jan 12, 2023
1 parent 0fce6bb commit 555ece0
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
27 changes: 26 additions & 1 deletion packages/react-reconciler/src/ReactFiberNewContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ import {REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED} from 'shared/ReactSymbols

const valueCursor: StackCursor<mixed> = createCursor(null);

let rendererCursorDEV: StackCursor<Object | null>;
if (__DEV__) {
rendererCursorDEV = createCursor(null);
}
let renderer2CursorDEV: StackCursor<Object | null>;
if (__DEV__) {
renderer2CursorDEV = createCursor(null);
}

let rendererSigil;
if (__DEV__) {
// Use this to detect multiple renderers using the same context
Expand Down Expand Up @@ -94,6 +103,8 @@ export function pushProvider<T>(

context._currentValue = nextValue;
if (__DEV__) {
push(rendererCursorDEV, context._currentRenderer, providerFiber);

if (
context._currentRenderer !== undefined &&
context._currentRenderer !== null &&
Expand All @@ -111,6 +122,8 @@ export function pushProvider<T>(

context._currentValue2 = nextValue;
if (__DEV__) {
push(renderer2CursorDEV, context._currentRenderer2, providerFiber);

if (
context._currentRenderer2 !== undefined &&
context._currentRenderer2 !== null &&
Expand All @@ -131,7 +144,7 @@ export function popProvider(
providerFiber: Fiber,
): void {
const currentValue = valueCursor.current;
pop(valueCursor, providerFiber);

if (isPrimaryRenderer) {
if (
enableServerContext &&
Expand All @@ -141,6 +154,11 @@ export function popProvider(
} else {
context._currentValue = currentValue;
}
if (__DEV__) {
const currentRenderer = rendererCursorDEV.current;
pop(rendererCursorDEV, providerFiber);
context._currentRenderer = currentRenderer;
}
} else {
if (
enableServerContext &&
Expand All @@ -150,7 +168,14 @@ export function popProvider(
} else {
context._currentValue2 = currentValue;
}
if (__DEV__) {
const currentRenderer2 = renderer2CursorDEV.current;
pop(renderer2CursorDEV, providerFiber);
context._currentRenderer2 = currentRenderer2;
}
}

pop(valueCursor, providerFiber);
}

export function scheduleContextWorkOnParentPath(
Expand Down
42 changes: 42 additions & 0 deletions packages/react-reconciler/src/__tests__/ReactNewContext-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,48 @@ describe('ReactNewContext', () => {
}
});

it('does not warn if multiple renderers use the same context sequentially', () => {
spyOnDev(console, 'error');
const Context = React.createContext(0);

function Foo(props) {
Scheduler.unstable_yieldValue('Foo');
return null;
}

function App(props) {
return (
<Context.Provider value={props.value}>
<Foo />
<Foo />
</Context.Provider>
);
}

if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.startTransition(() => {
ReactNoop.render(<App value={1} />);
});
} else {
ReactNoop.render(<App value={1} />);
}
expect(Scheduler).toFlushAndYield(['Foo', 'Foo']);

// Get a new copy of ReactNoop
jest.resetModules();
React = require('react');
ReactNoop = require('react-noop-renderer');
Scheduler = require('scheduler');

// Render the provider again using a different renderer
ReactNoop.render(<App value={1} />);
expect(Scheduler).toFlushAndYield(['Foo', 'Foo']);

if (__DEV__) {
expect(console.error).not.toHaveBeenCalled();
}
});

it('provider bails out if children and value are unchanged (like sCU)', () => {
const Context = React.createContext(0);

Expand Down

0 comments on commit 555ece0

Please sign in to comment.