Skip to content

Commit 5fce648

Browse files
authored
Revert "Disallow reading context during useMemo etc" (#14651)
* Revert "Add test coverage for readContext() on the server (#14649)" This reverts commit fe2ecd2. * Revert "Warn about incorrect use of useImperativeHandle() (#14647)" This reverts commit 8f45a7f. * Revert "Disallow reading context during useMemo etc (#14648)" This reverts commit 1fcbd22.
1 parent fe2ecd2 commit 5fce648

4 files changed

Lines changed: 12 additions & 110 deletions

File tree

‎packages/react-reconciler/src/ReactFiberClassComponent.js‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
importReactStrictModeWarningsfrom'./ReactStrictModeWarnings';
2121
import{isMounted}from'react-reconciler/reflection';
2222
import{getasgetInstance,setassetInstance}from'shared/ReactInstanceMap';
23+
importReactSharedInternalsfrom'shared/ReactSharedInternals';
2324
importshallowEqualfrom'shared/shallowEqual';
2425
importgetComponentNamefrom'shared/getComponentName';
2526
importinvariantfrom'shared/invariant';
@@ -47,14 +48,20 @@ import {
4748
hasContextChanged,
4849
emptyContextObject,
4950
}from'./ReactFiberContext';
50-
import{readContext}from'./ReactFiberNewContext';
5151
import{
5252
requestCurrentTime,
5353
computeExpirationForFiber,
5454
scheduleWork,
5555
flushPassiveEffects,
5656
}from'./ReactFiberScheduler';
5757

58+
constReactCurrentDispatcher=ReactSharedInternals.ReactCurrentDispatcher;
59+
60+
functionreadContext(contextType: any): any{
61+
constdispatcher=ReactCurrentDispatcher.current;
62+
returndispatcher.readContext(contextType);
63+
}
64+
5865
constfakeInternalInstance={};
5966
constisArray=Array.isArray;
6067

‎packages/react-reconciler/src/ReactFiberDispatcher.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
* @flow
88
*/
99

10+
import{readContext}from'./ReactFiberNewContext';
1011
import{
11-
readContext,
1212
useCallback,
1313
useContext,
1414
useEffect,

‎packages/react-reconciler/src/ReactFiberHooks.js‎

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type {HookEffectTag} from './ReactHookEffectTags';
1414

1515
import{NoWork}from'./ReactFiberExpirationTime';
1616
import{enableHooks}from'shared/ReactFeatureFlags';
17-
import{readContextasreadContextWithoutCheck}from'./ReactFiberNewContext';
17+
import{readContext}from'./ReactFiberNewContext';
1818
import{
1919
UpdateasUpdateEffect,
2020
PassiveasPassiveEffect,
@@ -284,7 +284,7 @@ export function resetHooks(): void {
284284

285285
// This is used to reset the state of this module when a component throws.
286286
// It's also called inside mountIndeterminateComponent if we determine the
287-
// component is a module-style component, and also in readContext() above.
287+
// component is a module-style component.
288288
renderExpirationTime=NoWork;
289289
currentlyRenderingFiber=null;
290290

@@ -394,7 +394,7 @@ export function useContext<T>(
394394
// Ensure we're in a function component (class components support only the
395395
// .unstable_read() form)
396396
resolveCurrentlyRenderingFiber();
397-
return readContextWithoutCheck(context, observedBits);
397+
return readContext(context, observedBits);
398398
}
399399

400400
exportfunctionuseState<S>(
@@ -785,29 +785,6 @@ export function useMemo<T>(
785785
returnnextValue;
786786
}
787787

788-
exportfunctionreadContext<T>(
789-
context: ReactContext<T>,
790-
observedBits: void | number | boolean,
791-
): T {
792-
// Forbid reading context inside Hooks.
793-
// The outer check tells us whether we're inside a Hook like useMemo().
794-
// However, it would also be true if we're rendering a class.
795-
if(currentlyRenderingFiber===null){
796-
// The inner check tells us we're currently in renderWithHooks() phase
797-
// rather than, for example, in a class or a context consumer.
798-
// Then we know it should be an error.
799-
if(renderExpirationTime!==NoWork){
800-
invariant(
801-
false,
802-
'Context can only be read inside the body of a component. '+
803-
'If you read context inside a Hook like useMemo or useReducer, '+
804-
'move the call directly into the component body.',
805-
);
806-
}
807-
}
808-
returnreadContextWithoutCheck(context,observedBits);
809-
}
810-
811788
functiondispatchAction<S,A>(
812789
fiber: Fiber,
813790
queue: UpdateQueue<S,A>,

‎packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js‎

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -672,88 +672,6 @@ describe('ReactHooks', () => {
672672
expect(root.toJSON()).toEqual('123');
673673
});
674674

675-
it('throws when reading context inside useMemo',()=>{
676-
const{useMemo, createContext}=React;
677-
constReactCurrentDispatcher=
678-
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
679-
.ReactCurrentDispatcher;
680-
681-
constThemeContext=createContext('light');
682-
functionApp(){
683-
returnuseMemo(()=>{
684-
returnReactCurrentDispatcher.current.readContext(ThemeContext);
685-
},[]);
686-
}
687-
688-
expect(()=>ReactTestRenderer.create(<App/>)).toThrow(
689-
'Context can only be read inside the body of a component',
690-
);
691-
});
692-
693-
it('throws when reading context inside useEffect',()=>{
694-
const{useEffect, createContext}=React;
695-
constReactCurrentDispatcher=
696-
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
697-
.ReactCurrentDispatcher;
698-
699-
constThemeContext=createContext('light');
700-
functionApp(){
701-
useEffect(()=>{
702-
ReactCurrentDispatcher.current.readContext(ThemeContext);
703-
});
704-
returnnull;
705-
}
706-
707-
constroot=ReactTestRenderer.create(<App/>);
708-
expect(()=>root.update(<App/>)).toThrow(
709-
// The exact message doesn't matter, just make sure we don't allow this
710-
"Cannot read property 'readContext' of null",
711-
);
712-
});
713-
714-
it('throws when reading context inside useLayoutEffect',()=>{
715-
const{useLayoutEffect, createContext}=React;
716-
constReactCurrentDispatcher=
717-
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
718-
.ReactCurrentDispatcher;
719-
720-
constThemeContext=createContext('light');
721-
functionApp(){
722-
useLayoutEffect(()=>{
723-
ReactCurrentDispatcher.current.readContext(ThemeContext);
724-
});
725-
returnnull;
726-
}
727-
728-
expect(()=>ReactTestRenderer.create(<App/>)).toThrow(
729-
// The exact message doesn't matter, just make sure we don't allow this
730-
"Cannot read property 'readContext' of null",
731-
);
732-
});
733-
734-
it('throws when reading context inside useReducer',()=>{
735-
const{useReducer, createContext}=React;
736-
constReactCurrentDispatcher=
737-
React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
738-
.ReactCurrentDispatcher;
739-
740-
constThemeContext=createContext('light');
741-
functionApp(){
742-
useReducer(
743-
()=>{
744-
ReactCurrentDispatcher.current.readContext(ThemeContext);
745-
},
746-
null,
747-
{},
748-
);
749-
returnnull;
750-
}
751-
752-
expect(()=>ReactTestRenderer.create(<App/>)).toThrow(
753-
'Context can only be read inside the body of a component.',
754-
);
755-
});
756-
757675
it('throws when calling hooks inside useReducer',()=>{
758676
const{useReducer, useRef}=React;
759677
functionApp(){

0 commit comments

Comments
 (0)