@samitouri / QOS-React-2 / commits / 555ece0cd1

Don't warn about concurrently rendering contexts if we finished rendering (#22797)

Closes https://github.com/facebook/react/issues/22796

Sebastian Silbermann committed Jan 12, 2023 at 13:17 UTC 555ece0cd14779abd5a1fc50f71625f9ada42bef
2 files changed +68 -1
packages/react-reconciler/src/ReactFiberNewContext.js
+26 -1
@@ -49,6 +49,15 @@ import {REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED} from 'shared/ReactSymbols
49
50 const valueCursor: StackCursor<mixed> = createCursor(null);
51
52 +let rendererCursorDEV: StackCursor<Object | null>;
53 +if (__DEV__) {
54 + rendererCursorDEV = createCursor(null);
55 +}
56 +let renderer2CursorDEV: StackCursor<Object | null>;
57 +if (__DEV__) {
58 + renderer2CursorDEV = createCursor(null);
59 +}
60 +
61 let rendererSigil;
62 if (__DEV__) {
63 // Use this to detect multiple renderers using the same context
@@ -94,6 +103,8 @@ export function pushProvider<T>(
103
104 context._currentValue = nextValue;
105 if (__DEV__) {
106 + push(rendererCursorDEV, context._currentRenderer, providerFiber);
107 +
108 if (
109 context._currentRenderer !== undefined &&
110 context._currentRenderer !== null &&
@@ -111,6 +122,8 @@ export function pushProvider<T>(
122
123 context._currentValue2 = nextValue;
124 if (__DEV__) {
125 + push(renderer2CursorDEV, context._currentRenderer2, providerFiber);
126 +
127 if (
128 context._currentRenderer2 !== undefined &&
129 context._currentRenderer2 !== null &&
@@ -131,7 +144,7 @@ export function popProvider(
144 providerFiber: Fiber,
145 ): void {
146 const currentValue = valueCursor.current;
134 - pop(valueCursor, providerFiber);
147 +
148 if (isPrimaryRenderer) {
149 if (
150 enableServerContext &&
@@ -141,6 +154,11 @@ export function popProvider(
154 } else {
155 context._currentValue = currentValue;
156 }
157 + if (__DEV__) {
158 + const currentRenderer = rendererCursorDEV.current;
159 + pop(rendererCursorDEV, providerFiber);
160 + context._currentRenderer = currentRenderer;
161 + }
162 } else {
163 if (
164 enableServerContext &&
@@ -150,7 +168,14 @@ export function popProvider(
168 } else {
169 context._currentValue2 = currentValue;
170 }
171 + if (__DEV__) {
172 + const currentRenderer2 = renderer2CursorDEV.current;
173 + pop(renderer2CursorDEV, providerFiber);
174 + context._currentRenderer2 = currentRenderer2;
175 + }
176 }
177 +
178 + pop(valueCursor, providerFiber);
179 }
180
181 export function scheduleContextWorkOnParentPath(
packages/react-reconciler/src/__tests__/ReactNewContext-test.js
+42
@@ -874,6 +874,48 @@ describe('ReactNewContext', () => {
874 }
875 });
876
877 + it('does not warn if multiple renderers use the same context sequentially', () => {
878 + spyOnDev(console, 'error');
879 + const Context = React.createContext(0);
880 +
881 + function Foo(props) {
882 + Scheduler.unstable_yieldValue('Foo');
883 + return null;
884 + }
885 +
886 + function App(props) {
887 + return (
888 + <Context.Provider value={props.value}>
889 + <Foo />
890 + <Foo />
891 + </Context.Provider>
892 + );
893 + }
894 +
895 + if (gate(flags => flags.enableSyncDefaultUpdates)) {
896 + React.startTransition(() => {
897 + ReactNoop.render(<App value={1} />);
898 + });
899 + } else {
900 + ReactNoop.render(<App value={1} />);
901 + }
902 + expect(Scheduler).toFlushAndYield(['Foo', 'Foo']);
903 +
904 + // Get a new copy of ReactNoop
905 + jest.resetModules();
906 + React = require('react');
907 + ReactNoop = require('react-noop-renderer');
908 + Scheduler = require('scheduler');
909 +
910 + // Render the provider again using a different renderer
911 + ReactNoop.render(<App value={1} />);
912 + expect(Scheduler).toFlushAndYield(['Foo', 'Foo']);
913 +
914 + if (__DEV__) {
915 + expect(console.error).not.toHaveBeenCalled();
916 + }
917 + });
918 +
919 it('provider bails out if children and value are unchanged (like sCU)', () => {
920 const Context = React.createContext(0);
921