-
Notifications
You must be signed in to change notification settings - Fork 50.2k
Deprecate context object as a consumer and add a warning message #13829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
c902bb5
bd3495c
6d7d7c0
773d69d
22f4359
e39a444
40fcddb
4b0c8a7
f174b6e
59917cd
072b0d4
26d6d2c
d058f6e
9149b17
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| */ | ||
|
|
||
| import type {ReactProviderType, ReactContext} from 'shared/ReactTypes'; | ||
| import lowPriorityWarning from 'shared/lowPriorityWarning'; | ||
| import type {Fiber} from 'react-reconciler/src/ReactFiber'; | ||
| import type {FiberRoot} from './ReactFiberRoot'; | ||
| import type {ExpirationTime} from './ReactFiberExpirationTime'; | ||
|
|
@@ -1096,12 +1097,31 @@ function updateContextProvider( | |
| return workInProgress.child; | ||
| } | ||
|
|
||
| let hasWarnedAboutUsingContextAsConsumer = false; | ||
|
|
||
| function updateContextConsumer( | ||
| current: Fiber | null, | ||
| workInProgress: Fiber, | ||
| renderExpirationTime: ExpirationTime, | ||
| ) { | ||
| const context: ReactContext<any> = workInProgress.type; | ||
| let context: ReactContext<any> = workInProgress.type; | ||
| if (__DEV__) { | ||
| if (workInProgress.type._context === undefined) { | ||
| if (!hasWarnedAboutUsingContextAsConsumer) { | ||
| hasWarnedAboutUsingContextAsConsumer = true; | ||
| lowPriorityWarning( | ||
| false, | ||
| 'You are using the Context from React.createContext() as a consumer.' + | ||
| 'The correct way is to use Context.Consumer as the consumer instead. ' + | ||
| 'This usage is deprecated and will be removed in the next major version.', | ||
|
||
| ); | ||
| } | ||
| } else { | ||
| // Context.Consumer is a separate object in DEV, where | ||
| // _context points back to the original context | ||
|
||
| context = workInProgress.type._context; | ||
|
||
| } | ||
| } | ||
| const newProps = workInProgress.pendingProps; | ||
| const render = newProps.children; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1190,12 +1190,12 @@ describe('ReactNewContext', () => { | |
|
|
||
| function FooAndBar() { | ||
| return ( | ||
| <FooContext> | ||
| <FooContext.Consumer> | ||
| {foo => { | ||
| const bar = BarContext.unstable_read(); | ||
| return <Text text={`Foo: ${foo}, Bar: ${bar}`} />; | ||
| }} | ||
| </FooContext> | ||
| </FooContext.Consumer> | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -1558,4 +1558,31 @@ Context fuzz tester error! Copy and paste the following line into the test suite | |
| } | ||
| }); | ||
| }); | ||
|
|
||
| it('should warn with an error message when using context as a consumer in DEV', () => { | ||
| const BarContext = React.createContext({value: 'bar-initial'}); | ||
| const BarConsumer = BarContext; | ||
|
|
||
| function Component() { | ||
| return ( | ||
| <React.Fragment> | ||
| <BarContext.Provider value={{value: 'bar-updated'}}> | ||
| <BarConsumer> | ||
| {({value}) => <div actual={value} expected="bar-updated" />} | ||
| </BarConsumer> | ||
| </BarContext.Provider> | ||
| </React.Fragment> | ||
| ); | ||
| } | ||
|
|
||
| expect(() => { | ||
| ReactNoop.render(<Component />); | ||
| ReactNoop.flush(); | ||
| }).toLowPriorityWarnDev( | ||
| 'You are using the Context from React.createContext() as a consumer.' + | ||
| 'The correct way is to use Context.Consumer as the consumer instead. ' + | ||
|
||
| 'This usage is deprecated and will be removed in the next major version.', | ||
| {withoutStack: true}, | ||
|
||
| ); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,7 +67,46 @@ export function createContext<T>( | |
| $$typeof: REACT_PROVIDER_TYPE, | ||
| _context: context, | ||
| }; | ||
| context.Consumer = context; | ||
|
|
||
| if (__DEV__) { | ||
| // A separate object, but proxies back to the original context object for | ||
| // backwards compatibility. It has a different $$typeof, so we can properly | ||
| // warn for the incorrect usage of Context as a Consumer. | ||
| context.Consumer = { | ||
| $$typeof: REACT_CONTEXT_TYPE, | ||
| _context: context, | ||
| get _calculateChangedBits() { | ||
|
||
| return context._calculateChangedBits; | ||
| }, | ||
| set _calculateChangedBits(_calculateChangedBits) { | ||
| context._calculateChangedBits = _calculateChangedBits; | ||
| }, | ||
| get _currentValue() { | ||
| return context._currentValue; | ||
| }, | ||
| set _currentValue(_currentValue) { | ||
| context._currentValue = _currentValue; | ||
| }, | ||
| get _currentValue2() { | ||
| return context._currentValue2; | ||
| }, | ||
| set _currentValue2(_currentValue2) { | ||
| context._currentValue2 = _currentValue2; | ||
| }, | ||
| Provider: context.Provider, | ||
| get Consumer() { | ||
| return context.Consumer; | ||
| }, | ||
| get unstable_read() { | ||
| return context.unstable_read; | ||
| }, | ||
| set unstable_read(unstable_read) { | ||
| context.unstable_read = unstable_read; | ||
| }, | ||
| }; | ||
| } else { | ||
| context.Consumer = context; | ||
| } | ||
| context.unstable_read = readContext.bind(null, context); | ||
|
|
||
| if (__DEV__) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this just be
context._context? To avoid extra reads (even in DEV).