[private] Disallow useContext in class components
This commit is contained in:
committed by
Andrew Clark
parent
2888e06af6
commit
13cd5a2d20
@@ -9,26 +9,28 @@
|
||||
|
||||
import {readContext} from './ReactFiberNewContext';
|
||||
import {
|
||||
useState,
|
||||
useReducer,
|
||||
useEffect,
|
||||
useMutationEffect,
|
||||
useLayoutEffect,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useRef,
|
||||
useAPI,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useMutationEffect,
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
} from './ReactFiberHooks';
|
||||
|
||||
export const Dispatcher = {
|
||||
readContext,
|
||||
useState,
|
||||
useReducer,
|
||||
useEffect,
|
||||
useMutationEffect,
|
||||
useLayoutEffect,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useRef,
|
||||
useAPI,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useMutationEffect,
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
};
|
||||
|
||||
12
packages/react-reconciler/src/ReactFiberHooks.js
vendored
12
packages/react-reconciler/src/ReactFiberHooks.js
vendored
@@ -7,11 +7,13 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {ReactContext} from 'shared/ReactTypes';
|
||||
import type {Fiber} from './ReactFiber';
|
||||
import type {ExpirationTime} from './ReactFiberExpirationTime';
|
||||
import type {HookEffectTag} from './ReactHookEffectTags';
|
||||
|
||||
import {NoWork} from './ReactFiberExpirationTime';
|
||||
import {readContext} from './ReactFiberNewContext';
|
||||
import {
|
||||
Snapshot as SnapshotEffect,
|
||||
Update as UpdateEffect,
|
||||
@@ -318,6 +320,16 @@ function basicStateReducer<S>(state: S, action: BasicStateAction<S>): S {
|
||||
return typeof action === 'function' ? action(state) : action;
|
||||
}
|
||||
|
||||
export function useContext<T>(
|
||||
context: ReactContext<T>,
|
||||
observedBits: void | number | boolean,
|
||||
): T {
|
||||
// Ensure we're in a functional component (class components support only the
|
||||
// .unstable_read() form)
|
||||
resolveCurrentlyRenderingFiber();
|
||||
return readContext(context, observedBits);
|
||||
}
|
||||
|
||||
export function useState<S>(
|
||||
initialState: S | (() => S),
|
||||
): [S, Dispatch<S, BasicStateAction<S>>] {
|
||||
|
||||
@@ -56,12 +56,12 @@ describe('ReactNewContext', () => {
|
||||
},
|
||||
);
|
||||
sharedContextTests(
|
||||
'useContext inside class component',
|
||||
'unstable_read inside class component',
|
||||
Context =>
|
||||
class Consumer extends React.Component {
|
||||
render() {
|
||||
const observedBits = this.props.unstable_observedBits;
|
||||
const contextValue = useContext(Context, observedBits);
|
||||
const contextValue = Context.unstable_read(observedBits);
|
||||
const render = this.props.children;
|
||||
return render(contextValue);
|
||||
}
|
||||
@@ -1195,7 +1195,7 @@ describe('ReactNewContext', () => {
|
||||
return (
|
||||
<FooContext>
|
||||
{foo => {
|
||||
const bar = useContext(BarContext);
|
||||
const bar = BarContext.unstable_read();
|
||||
return <Text text={`Foo: ${foo}, Bar: ${bar}`} />;
|
||||
}}
|
||||
</FooContext>
|
||||
@@ -1330,6 +1330,19 @@ describe('ReactNewContext', () => {
|
||||
span('Baz: 2'),
|
||||
]);
|
||||
});
|
||||
|
||||
it('throws when used in a class component', () => {
|
||||
const Context = React.createContext(0);
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return useContext(Context);
|
||||
}
|
||||
}
|
||||
ReactNoop.render(<Foo />);
|
||||
expect(ReactNoop.flush).toThrow(
|
||||
'Hooks can only be called inside the body of a functional component.',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('unwinds after errors in complete phase', () => {
|
||||
|
||||
@@ -24,20 +24,21 @@ import {
|
||||
cloneElement,
|
||||
isValidElement,
|
||||
} from './ReactElement';
|
||||
import {readContext, createContext} from './ReactContext';
|
||||
import {createContext} from './ReactContext';
|
||||
import {lazy} from './ReactLazy';
|
||||
import forwardRef from './forwardRef';
|
||||
import pure from './pure';
|
||||
import {
|
||||
useState,
|
||||
useAPI,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useMutationEffect,
|
||||
useReducer,
|
||||
useRef,
|
||||
useEffect,
|
||||
useMutationEffect,
|
||||
useLayoutEffect,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useAPI,
|
||||
useState,
|
||||
} from './ReactHooks';
|
||||
import {
|
||||
createElementWithValidation,
|
||||
@@ -84,16 +85,16 @@ if (enableSuspense) {
|
||||
}
|
||||
|
||||
if (enableHooks_DEPRECATED) {
|
||||
React.useContext = readContext;
|
||||
React.useState = useState;
|
||||
React.useAPI = useAPI;
|
||||
React.useCallback = useCallback;
|
||||
React.useContext = useContext;
|
||||
React.useEffect = useEffect;
|
||||
React.useLayoutEffect = useLayoutEffect;
|
||||
React.useMemo = useMemo;
|
||||
React.useMutationEffect = useMutationEffect;
|
||||
React.useReducer = useReducer;
|
||||
React.useRef = useRef;
|
||||
React.useEffect = useEffect;
|
||||
React.useMutationEffect = useMutationEffect;
|
||||
React.useLayoutEffect = useLayoutEffect;
|
||||
React.useCallback = useCallback;
|
||||
React.useMemo = useMemo;
|
||||
React.useAPI = useAPI;
|
||||
React.useState = useState;
|
||||
}
|
||||
|
||||
export default React;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {ReactContext} from 'shared/ReactTypes';
|
||||
import invariant from 'shared/invariant';
|
||||
|
||||
import ReactCurrentOwner from './ReactCurrentOwner';
|
||||
@@ -20,6 +21,14 @@ function resolveDispatcher() {
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
export function useContext<T>(
|
||||
context: ReactContext<T>,
|
||||
observedBits: void | number | boolean,
|
||||
): T {
|
||||
const dispatcher = resolveDispatcher();
|
||||
return dispatcher.useContext(context, observedBits);
|
||||
}
|
||||
|
||||
export function useState<S>(initialState: S | (() => S)) {
|
||||
const dispatcher = resolveDispatcher();
|
||||
return dispatcher.useState(initialState);
|
||||
|
||||
Reference in New Issue
Block a user