mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove propTypes checks for legacy context (#28324)
Part of https://github.com/facebook/react/pull/28207, this is easy to land in isolation. The approach I'm taking is slightly different — instead of leaving validation on for legacy context, I disable the validation (it's DEV-only) and leave just the parts that drive the runtime logic. I.e. `contexTypes` and `childContextTypes` *values* are now ignored, the keys are used just like before.
This commit is contained in:
@@ -14,7 +14,6 @@ import {isFiberMounted} from './ReactFiberTreeReflection';
|
||||
import {disableLegacyContext} from 'shared/ReactFeatureFlags';
|
||||
import {ClassComponent, HostRoot} from './ReactWorkTags';
|
||||
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
|
||||
import checkPropTypes from 'shared/checkPropTypes';
|
||||
|
||||
import {createCursor, push, pop} from './ReactFiberStack';
|
||||
|
||||
@@ -101,11 +100,6 @@ function getMaskedContext(
|
||||
context[key] = unmaskedContext[key];
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
const name = getComponentNameFromFiber(workInProgress) || 'Unknown';
|
||||
checkPropTypes(contextTypes, context, 'context', name);
|
||||
}
|
||||
|
||||
// Cache unmasked context so we can avoid recreating masked context unless necessary.
|
||||
// Context is created before the class component is instantiated so check for instance.
|
||||
if (instance) {
|
||||
@@ -212,10 +206,6 @@ function processChildContext(
|
||||
);
|
||||
}
|
||||
}
|
||||
if (__DEV__) {
|
||||
const name = getComponentNameFromFiber(fiber) || 'Unknown';
|
||||
checkPropTypes(childContextTypes, childContext, 'child context', name);
|
||||
}
|
||||
|
||||
return {...parentContext, ...childContext};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
let PropTypes;
|
||||
let React;
|
||||
let ReactDOMClient;
|
||||
let ReactDOMServer;
|
||||
let ReactTestUtils;
|
||||
let act;
|
||||
|
||||
@@ -29,7 +28,6 @@ describe('ReactContextValidator', () => {
|
||||
PropTypes = require('prop-types');
|
||||
React = require('react');
|
||||
ReactDOMClient = require('react-dom/client');
|
||||
ReactDOMServer = require('react-dom/server');
|
||||
ReactTestUtils = require('react-dom/test-utils');
|
||||
act = require('internal-test-utils').act;
|
||||
});
|
||||
@@ -159,136 +157,6 @@ describe('ReactContextValidator', () => {
|
||||
expect(componentDidUpdateContext).toEqual({foo: 'def'});
|
||||
});
|
||||
|
||||
// @gate !disableLegacyContext || !__DEV__
|
||||
it('should check context types', () => {
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
Component.contextTypes = {
|
||||
foo: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Component />)).toErrorDev(
|
||||
'Warning: Failed context type: ' +
|
||||
'The context `foo` is marked as required in `Component`, but its value ' +
|
||||
'is `undefined`.\n' +
|
||||
' in Component (at **)',
|
||||
);
|
||||
|
||||
class ComponentInFooStringContext extends React.Component {
|
||||
getChildContext() {
|
||||
return {
|
||||
foo: this.props.fooValue,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return <Component />;
|
||||
}
|
||||
}
|
||||
ComponentInFooStringContext.childContextTypes = {
|
||||
foo: PropTypes.string,
|
||||
};
|
||||
|
||||
// No additional errors expected
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<ComponentInFooStringContext fooValue={'bar'} />,
|
||||
);
|
||||
|
||||
class ComponentInFooNumberContext extends React.Component {
|
||||
getChildContext() {
|
||||
return {
|
||||
foo: this.props.fooValue,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return <Component />;
|
||||
}
|
||||
}
|
||||
ComponentInFooNumberContext.childContextTypes = {
|
||||
foo: PropTypes.number,
|
||||
};
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<ComponentInFooNumberContext fooValue={123} />,
|
||||
),
|
||||
).toErrorDev(
|
||||
'Warning: Failed context type: ' +
|
||||
'Invalid context `foo` of type `number` supplied ' +
|
||||
'to `Component`, expected `string`.\n' +
|
||||
' in Component (at **)\n' +
|
||||
' in ComponentInFooNumberContext (at **)',
|
||||
);
|
||||
});
|
||||
|
||||
// @gate !disableLegacyContext || !__DEV__
|
||||
it('should check child context types', () => {
|
||||
class Component extends React.Component {
|
||||
getChildContext() {
|
||||
return this.props.testContext;
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
Component.childContextTypes = {
|
||||
foo: PropTypes.string.isRequired,
|
||||
bar: PropTypes.number,
|
||||
};
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<Component testContext={{bar: 123}} />),
|
||||
).toErrorDev(
|
||||
'Warning: Failed child context type: ' +
|
||||
'The child context `foo` is marked as required in `Component`, but its ' +
|
||||
'value is `undefined`.\n' +
|
||||
' in Component (at **)',
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<Component testContext={{foo: 123}} />),
|
||||
).toErrorDev(
|
||||
'Warning: Failed child context type: ' +
|
||||
'Invalid child context `foo` of type `number` ' +
|
||||
'supplied to `Component`, expected `string`.\n' +
|
||||
' in Component (at **)',
|
||||
);
|
||||
|
||||
// No additional errors expected
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component testContext={{foo: 'foo', bar: 123}} />,
|
||||
);
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component testContext={{foo: 'foo'}} />);
|
||||
});
|
||||
|
||||
it('warns of incorrect prop types on context provider', () => {
|
||||
const TestContext = React.createContext();
|
||||
|
||||
TestContext.Provider.propTypes = {
|
||||
value: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<TestContext.Provider value="val" />);
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
return <TestContext.Provider value={undefined} />;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Component />)).toErrorDev(
|
||||
'Warning: Failed prop type: The prop `value` is marked as required in ' +
|
||||
'`Context.Provider`, but its value is `undefined`.\n' +
|
||||
' in Component (at **)',
|
||||
);
|
||||
});
|
||||
|
||||
// TODO (bvaughn) Remove this test and the associated behavior in the future.
|
||||
// It has only been added in Fiber to match the (unintentional) behavior in Stack.
|
||||
// @gate !disableLegacyContext || !__DEV__
|
||||
@@ -371,8 +239,6 @@ describe('ReactContextValidator', () => {
|
||||
'Warning: MiddleMissingContext.childContextTypes is specified but there is no ' +
|
||||
'getChildContext() method on the instance. You can either define getChildContext() ' +
|
||||
'on MiddleMissingContext or remove childContextTypes from it.',
|
||||
'Warning: Failed context type: The context `bar` is marked as required ' +
|
||||
'in `ChildContextConsumer`, but its value is `undefined`.',
|
||||
]);
|
||||
expect(childContext.bar).toBeUndefined();
|
||||
expect(childContext.foo).toBe('FOO');
|
||||
@@ -699,24 +565,4 @@ describe('ReactContextValidator', () => {
|
||||
'Warning: ComponentB: Function components do not support contextType.',
|
||||
);
|
||||
});
|
||||
|
||||
it('should honor a displayName if set on the context type', () => {
|
||||
const Context = React.createContext(null);
|
||||
Context.displayName = 'MyContextType';
|
||||
function Validator() {
|
||||
return null;
|
||||
}
|
||||
Validator.propTypes = {dontPassToSeeErrorStack: PropTypes.bool.isRequired};
|
||||
|
||||
expect(() => {
|
||||
ReactDOMServer.renderToStaticMarkup(
|
||||
<Context.Provider>
|
||||
<Context.Consumer>{() => <Validator />}</Context.Consumer>
|
||||
</Context.Provider>,
|
||||
);
|
||||
}).toErrorDev(
|
||||
'Warning: Failed prop type: The prop `dontPassToSeeErrorStack` is marked as required in `Validator`, but its value is `undefined`.\n' +
|
||||
' in Validator (at **)',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -312,7 +312,7 @@ describe('ReactJSXElementValidator', () => {
|
||||
});
|
||||
|
||||
// @gate !disableLegacyContext || !__DEV__
|
||||
it('should warn on invalid context types', () => {
|
||||
it('should not warn on invalid context types', () => {
|
||||
class NullContextTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
@@ -321,12 +321,7 @@ describe('ReactJSXElementValidator', () => {
|
||||
NullContextTypeComponent.contextTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullContextTypeComponent />),
|
||||
).toErrorDev(
|
||||
'NullContextTypeComponent: context type `prop` is invalid; it must ' +
|
||||
'be a function, usually from the `prop-types` package,',
|
||||
);
|
||||
ReactTestUtils.renderIntoDocument(<NullContextTypeComponent />);
|
||||
});
|
||||
|
||||
it('should warn if getDefaultProps is specified on the class', () => {
|
||||
|
||||
Reference in New Issue
Block a user