@samitouri / QOS-React-2 / commits / 5fce6488ce

Revert "Disallow reading context during useMemo etc" (#14651)

* Revert "Add test coverage for readContext() on the server (#14649)" This reverts commit fe2ecd276e9b9e57a49ddf2d86ff01677b69b493. * Revert "Warn about incorrect use of useImperativeHandle() (#14647)" This reverts commit 8f45a7fdc469c6d88ca5ca105095b03dd4e862e1. * Revert "Disallow reading context during useMemo etc (#14648)" This reverts commit 1fcbd22431d97e404c1f684744dc543b6c22b076.

Dan Abramov committed Jan 21, 2019 at 20:28 UTC 5fce6488ce1dc97e31515a47ff409d32ab722d65
4 files changed +12 -110
packages/react-reconciler/src/ReactFiberClassComponent.js
+8 -1
@@ -20,6 +20,7 @@ import {
20 import ReactStrictModeWarnings from './ReactStrictModeWarnings';
21 import {isMounted} from 'react-reconciler/reflection';
22 import {get as getInstance, set as setInstance} from 'shared/ReactInstanceMap';
23 +import ReactSharedInternals from 'shared/ReactSharedInternals';
24 import shallowEqual from 'shared/shallowEqual';
25 import getComponentName from 'shared/getComponentName';
26 import invariant from 'shared/invariant';
@@ -47,7 +48,6 @@ import {
48 hasContextChanged,
49 emptyContextObject,
50 } from './ReactFiberContext';
50 -import {readContext} from './ReactFiberNewContext';
51 import {
52 requestCurrentTime,
53 computeExpirationForFiber,
@@ -55,6 +55,13 @@ import {
55 flushPassiveEffects,
56 } from './ReactFiberScheduler';
57
58 +const ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
59 +
60 +function readContext(contextType: any): any {
61 + const dispatcher = ReactCurrentDispatcher.current;
62 + return dispatcher.readContext(contextType);
63 +}
64 +
65 const fakeInternalInstance = {};
66 const isArray = Array.isArray;
67
packages/react-reconciler/src/ReactFiberDispatcher.js
+1 -1
@@ -7,8 +7,8 @@
7 * @flow
8 */
9
10 +import {readContext} from './ReactFiberNewContext';
11 import {
11 - readContext,
12 useCallback,
13 useContext,
14 useEffect,
packages/react-reconciler/src/ReactFiberHooks.js
+3 -26
@@ -14,7 +14,7 @@ import type {HookEffectTag} from './ReactHookEffectTags';
14
15 import {NoWork} from './ReactFiberExpirationTime';
16 import {enableHooks} from 'shared/ReactFeatureFlags';
17 -import {readContext as readContextWithoutCheck} from './ReactFiberNewContext';
17 +import {readContext} from './ReactFiberNewContext';
18 import {
19 Update as UpdateEffect,
20 Passive as PassiveEffect,
@@ -284,7 +284,7 @@ export function resetHooks(): void {
284
285 // This is used to reset the state of this module when a component throws.
286 // 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.
288 renderExpirationTime = NoWork;
289 currentlyRenderingFiber = null;
290
@@ -394,7 +394,7 @@ export function useContext<T>(
394 // Ensure we're in a function component (class components support only the
395 // .unstable_read() form)
396 resolveCurrentlyRenderingFiber();
397 - return readContextWithoutCheck(context, observedBits);
397 + return readContext(context, observedBits);
398 }
399
400 export function useState<S>(
@@ -785,29 +785,6 @@ export function useMemo<T>(
785 return nextValue;
786 }
787
788 -export function readContext<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 - return readContextWithoutCheck(context, observedBits);
809 -}
810 -
788 function dispatchAction<S, A>(
789 fiber: Fiber,
790 queue: UpdateQueue<S, A>,
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
-82
@@ -672,88 +672,6 @@ describe('ReactHooks', () => {
672 expect(root.toJSON()).toEqual('123');
673 });
674
675 - it('throws when reading context inside useMemo', () => {
676 - const {useMemo, createContext} = React;
677 - const ReactCurrentDispatcher =
678 - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
679 - .ReactCurrentDispatcher;
680 -
681 - const ThemeContext = createContext('light');
682 - function App() {
683 - return useMemo(() => {
684 - return ReactCurrentDispatcher.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 - const ReactCurrentDispatcher =
696 - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
697 - .ReactCurrentDispatcher;
698 -
699 - const ThemeContext = createContext('light');
700 - function App() {
701 - useEffect(() => {
702 - ReactCurrentDispatcher.current.readContext(ThemeContext);
703 - });
704 - return null;
705 - }
706 -
707 - const root = 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 - const ReactCurrentDispatcher =
717 - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
718 - .ReactCurrentDispatcher;
719 -
720 - const ThemeContext = createContext('light');
721 - function App() {
722 - useLayoutEffect(() => {
723 - ReactCurrentDispatcher.current.readContext(ThemeContext);
724 - });
725 - return null;
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 - const ReactCurrentDispatcher =
737 - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
738 - .ReactCurrentDispatcher;
739 -
740 - const ThemeContext = createContext('light');
741 - function App() {
742 - useReducer(
743 - () => {
744 - ReactCurrentDispatcher.current.readContext(ThemeContext);
745 - },
746 - null,
747 - {},
748 - );
749 - return null;
750 - }
751 -
752 - expect(() => ReactTestRenderer.create(<App />)).toThrow(
753 - 'Context can only be read inside the body of a component.',
754 - );
755 - });
756 -
675 it('throws when calling hooks inside useReducer', () => {
676 const {useReducer, useRef} = React;
677 function App() {