Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7685b55

Browse files
authored
Remove unstable_read() in favor of direct dispatcher call (facebook#13861)
* Remove unstable_read() in favor of direct dispatcher call * This no longer throws immediately
1 parent 21a79a1 commit 7685b55

File tree

7 files changed

+41
-78
lines changed

7 files changed

+41
-78
lines changed

packages/react-reconciler/src/ReactFiberClassComponent.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
import ReactStrictModeWarnings from './ReactStrictModeWarnings';
2121
import {isMounted} from 'react-reconciler/reflection';
2222
import * as ReactInstanceMap from 'shared/ReactInstanceMap';
23+
import ReactSharedInternals from 'shared/ReactSharedInternals';
2324
import shallowEqual from 'shared/shallowEqual';
2425
import getComponentName from 'shared/getComponentName';
2526
import invariant from 'shared/invariant';
@@ -50,6 +51,13 @@ import {
5051
scheduleWork,
5152
} from './ReactFiberScheduler';
5253

54+
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
55+
56+
function readContext(contextType: any): any {
57+
const dispatcher = ReactCurrentOwner.currentDispatcher;
58+
return dispatcher.readContext(contextType);
59+
}
60+
5361
const fakeInternalInstance = {};
5462
const isArray = Array.isArray;
5563

@@ -508,7 +516,7 @@ function constructClassInstance(
508516
if (typeof contextType === 'object' && contextType !== null) {
509517
if (__DEV__) {
510518
if (
511-
typeof contextType.unstable_read !== 'function' &&
519+
contextType.Consumer === undefined &&
512520
!didWarnAboutInvalidateContextType.has(ctor)
513521
) {
514522
didWarnAboutInvalidateContextType.add(ctor);
@@ -522,7 +530,7 @@ function constructClassInstance(
522530
}
523531
}
524532

525-
context = (contextType: any).unstable_read();
533+
context = readContext((contextType: any));
526534
} else {
527535
unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
528536
const contextTypes = ctor.contextTypes;
@@ -725,7 +733,7 @@ function mountClassInstance(
725733

726734
const contextType = ctor.contextType;
727735
if (typeof contextType === 'object' && contextType !== null) {
728-
instance.context = (contextType: any).unstable_read();
736+
instance.context = readContext(contextType);
729737
} else {
730738
const unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
731739
instance.context = getMaskedContext(workInProgress, unmaskedContext);
@@ -833,7 +841,7 @@ function resumeMountClassInstance(
833841
const contextType = ctor.contextType;
834842
let nextContext;
835843
if (typeof contextType === 'object' && contextType !== null) {
836-
nextContext = (contextType: any).unstable_read();
844+
nextContext = readContext(contextType);
837845
} else {
838846
const nextLegacyUnmaskedContext = getUnmaskedContext(
839847
workInProgress,
@@ -979,7 +987,7 @@ function updateClassInstance(
979987
const contextType = ctor.contextType;
980988
let nextContext;
981989
if (typeof contextType === 'object' && contextType !== null) {
982-
nextContext = (contextType: any).unstable_read();
990+
nextContext = readContext(contextType);
983991
} else {
984992
const nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
985993
nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);

packages/react-reconciler/src/ReactFiberNewContext.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ export function readContext<T>(
302302
if (lastContextDependency === null) {
303303
invariant(
304304
currentlyRenderingFiber !== null,
305-
'Context.unstable_read(): Context can only be read while React is ' +
305+
'Context can only be read while React is ' +
306306
'rendering, e.g. inside the render method or getDerivedStateFromProps.',
307307
);
308308
// This is the first dependency in the list

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

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,33 @@ describe('ReactNewContext', () => {
3939
return {type: 'span', children: [], prop};
4040
}
4141

42+
function readContext(Context, observedBits) {
43+
const dispatcher =
44+
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner
45+
.currentDispatcher;
46+
return dispatcher.readContext(Context, observedBits);
47+
}
48+
4249
// We have several ways of reading from context. sharedContextTests runs
4350
// a suite of tests for a given context consumer implementation.
4451
sharedContextTests('Context.Consumer', Context => Context.Consumer);
4552
sharedContextTests(
46-
'Context.unstable_read inside function component',
53+
'readContext(Context) inside function component',
4754
Context =>
4855
function Consumer(props) {
4956
const observedBits = props.unstable_observedBits;
50-
const contextValue = Context.unstable_read(observedBits);
57+
const contextValue = readContext(Context, observedBits);
5158
const render = props.children;
5259
return render(contextValue);
5360
},
5461
);
5562
sharedContextTests(
56-
'Context.unstable_read inside class component',
63+
'readContext(Context) inside class component',
5764
Context =>
5865
class Consumer extends React.Component {
5966
render() {
6067
const observedBits = this.props.unstable_observedBits;
61-
const contextValue = Context.unstable_read(observedBits);
68+
const contextValue = readContext(Context, observedBits);
6269
const render = this.props.children;
6370
return render(contextValue);
6471
}
@@ -1192,7 +1199,7 @@ describe('ReactNewContext', () => {
11921199
return (
11931200
<FooContext.Consumer>
11941201
{foo => {
1195-
const bar = BarContext.unstable_read();
1202+
const bar = readContext(BarContext);
11961203
return <Text text={`Foo: ${foo}, Bar: ${bar}`} />;
11971204
}}
11981205
</FooContext.Consumer>
@@ -1236,7 +1243,7 @@ describe('ReactNewContext', () => {
12361243
});
12371244
});
12381245

1239-
describe('unstable_readContext', () => {
1246+
describe('readContext', () => {
12401247
it('can use the same context multiple times in the same function', () => {
12411248
const Context = React.createContext({foo: 0, bar: 0, baz: 0}, (a, b) => {
12421249
let result = 0;
@@ -1262,13 +1269,13 @@ describe('ReactNewContext', () => {
12621269
}
12631270

12641271
function FooAndBar() {
1265-
const {foo} = Context.unstable_read(0b001);
1266-
const {bar} = Context.unstable_read(0b010);
1272+
const {foo} = readContext(Context, 0b001);
1273+
const {bar} = readContext(Context, 0b010);
12671274
return <Text text={`Foo: ${foo}, Bar: ${bar}`} />;
12681275
}
12691276

12701277
function Baz() {
1271-
const {baz} = Context.unstable_read(0b100);
1278+
const {baz} = readContext(Context, 0b100);
12721279
return <Text text={'Baz: ' + baz} />;
12731280
}
12741281

@@ -1631,33 +1638,6 @@ Context fuzz tester error! Copy and paste the following line into the test suite
16311638
);
16321639
});
16331640

1634-
it('should warn with an error message when using Context.Consumer.unstable_read() DEV', () => {
1635-
const BarContext = React.createContext({value: 'bar-initial'});
1636-
1637-
function Child() {
1638-
let value = BarContext.Consumer.unstable_read();
1639-
return <div actual={value} expected="bar-updated" />;
1640-
}
1641-
1642-
function Component() {
1643-
return (
1644-
<React.Fragment>
1645-
<BarContext.Provider value={{value: 'bar-updated'}}>
1646-
<Child />
1647-
</BarContext.Provider>
1648-
</React.Fragment>
1649-
);
1650-
}
1651-
1652-
expect(() => {
1653-
ReactNoop.render(<Component />);
1654-
ReactNoop.flush();
1655-
}).toWarnDev(
1656-
'Calling Context.Consumer.unstable_read() is not supported and will be removed in ' +
1657-
'a future major release. Did you mean to render Context.unstable_read() instead?',
1658-
);
1659-
});
1660-
16611641
it('should warn with an error message when using Context.Consumer.Provider DEV', () => {
16621642
const BarContext = React.createContext({value: 'bar-initial'});
16631643

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,15 @@ describe('pure', () => {
9090

9191
const CountContext = React.createContext(0);
9292

93+
function readContext(Context) {
94+
const dispatcher =
95+
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
96+
.ReactCurrentOwner.currentDispatcher;
97+
return dispatcher.readContext(Context);
98+
}
99+
93100
function Counter(props) {
94-
const count = CountContext.unstable_read();
101+
const count = readContext(CountContext);
95102
return <Text text={`${props.label}: ${count}`} />;
96103
}
97104
Counter = pure(Counter);

packages/react/src/ReactContext.js

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,9 @@ import {REACT_PROVIDER_TYPE, REACT_CONTEXT_TYPE} from 'shared/ReactSymbols';
1111

1212
import type {ReactContext} from 'shared/ReactTypes';
1313

14-
import invariant from 'shared/invariant';
1514
import warningWithoutStack from 'shared/warningWithoutStack';
1615
import warning from 'shared/warning';
1716

18-
import ReactCurrentOwner from './ReactCurrentOwner';
19-
20-
export function readContext<T>(
21-
context: ReactContext<T>,
22-
observedBits: void | number | boolean,
23-
): T {
24-
const dispatcher = ReactCurrentOwner.currentDispatcher;
25-
invariant(
26-
dispatcher !== null,
27-
'Context.unstable_read(): Context can only be read while React is ' +
28-
'rendering, e.g. inside the render method or getDerivedStateFromProps.',
29-
);
30-
return dispatcher.readContext(context, observedBits);
31-
}
32-
3317
export function createContext<T>(
3418
defaultValue: T,
3519
calculateChangedBits: ?(a: T, b: T) => number,
@@ -61,18 +45,14 @@ export function createContext<T>(
6145
// These are circular
6246
Provider: (null: any),
6347
Consumer: (null: any),
64-
unstable_read: (null: any),
6548
};
6649

6750
context.Provider = {
6851
$$typeof: REACT_PROVIDER_TYPE,
6952
_context: context,
7053
};
7154

72-
context.unstable_read = readContext.bind(null, context);
73-
7455
let hasWarnedAboutUsingNestedContextConsumers = false;
75-
let hasWarnedAboutUsingConsumerUnstableRead = false;
7656
let hasWarnedAboutUsingConsumerProvider = false;
7757

7858
if (__DEV__) {
@@ -83,17 +63,6 @@ export function createContext<T>(
8363
$$typeof: REACT_CONTEXT_TYPE,
8464
_context: context,
8565
_calculateChangedBits: context._calculateChangedBits,
86-
unstable_read() {
87-
if (!hasWarnedAboutUsingConsumerUnstableRead) {
88-
hasWarnedAboutUsingConsumerUnstableRead = true;
89-
warning(
90-
false,
91-
'Calling Context.Consumer.unstable_read() is not supported and will be removed in ' +
92-
'a future major release. Did you mean to render Context.unstable_read() instead?',
93-
);
94-
}
95-
return context.unstable_read();
96-
},
9766
};
9867
// $FlowFixMe: Flow complains about not setting a value, which is intentional here
9968
Object.defineProperties(Consumer, {

packages/react/src/__tests__/ReactContextValidator-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ describe('ReactContextValidator', () => {
556556
}
557557

558558
expect(() => {
559-
expect(() => ReactTestUtils.renderIntoDocument(<ComponentA />)).toThrow();
559+
ReactTestUtils.renderIntoDocument(<ComponentA />);
560560
}).toWarnDev(
561561
'Warning: ComponentA defines an invalid contextType. ' +
562562
'contextType should point to the Context object returned by React.createContext(). ' +
@@ -565,10 +565,10 @@ describe('ReactContextValidator', () => {
565565
);
566566

567567
// Warnings should be deduped by component type
568-
expect(() => ReactTestUtils.renderIntoDocument(<ComponentA />)).toThrow();
568+
ReactTestUtils.renderIntoDocument(<ComponentA />);
569569

570570
expect(() => {
571-
expect(() => ReactTestUtils.renderIntoDocument(<ComponentB />)).toThrow();
571+
ReactTestUtils.renderIntoDocument(<ComponentB />);
572572
}).toWarnDev(
573573
'Warning: ComponentB defines an invalid contextType. ' +
574574
'contextType should point to the Context object returned by React.createContext(). ' +

packages/shared/ReactTypes.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ export type ReactContext<T> = {
5454
$$typeof: Symbol | number,
5555
Consumer: ReactContext<T>,
5656
Provider: ReactProviderType<T>,
57-
unstable_read: () => T,
5857

5958
_calculateChangedBits: ((a: T, b: T) => number) | null,
6059

0 commit comments

Comments
 (0)