Skip to content

Commit 81ec618

Browse files
committed
Remove propTypes checks for legacy context (#28324)
Part of #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.
1 parent b71f399 commit 81ec618

File tree

3 files changed

+2
-171
lines changed

3 files changed

+2
-171
lines changed

packages/react-reconciler/src/ReactFiberContext.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {isFiberMounted} from './ReactFiberTreeReflection';
1414
import {disableLegacyContext} from 'shared/ReactFeatureFlags';
1515
import {ClassComponent, HostRoot} from './ReactWorkTags';
1616
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
17-
import checkPropTypes from 'shared/checkPropTypes';
1817

1918
import {createCursor, push, pop} from './ReactFiberStack';
2019

@@ -101,11 +100,6 @@ function getMaskedContext(
101100
context[key] = unmaskedContext[key];
102101
}
103102

104-
if (__DEV__) {
105-
const name = getComponentNameFromFiber(workInProgress) || 'Unknown';
106-
checkPropTypes(contextTypes, context, 'context', name);
107-
}
108-
109103
// Cache unmasked context so we can avoid recreating masked context unless necessary.
110104
// Context is created before the class component is instantiated so check for instance.
111105
if (instance) {
@@ -212,10 +206,6 @@ function processChildContext(
212206
);
213207
}
214208
}
215-
if (__DEV__) {
216-
const name = getComponentNameFromFiber(fiber) || 'Unknown';
217-
checkPropTypes(childContextTypes, childContext, 'child context', name);
218-
}
219209

220210
return {...parentContext, ...childContext};
221211
}

packages/react/src/__tests__/ReactContextValidator-test.js

Lines changed: 0 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
let PropTypes;
1919
let React;
2020
let ReactDOMClient;
21-
let ReactDOMServer;
2221
let ReactTestUtils;
2322
let act;
2423

@@ -29,7 +28,6 @@ describe('ReactContextValidator', () => {
2928
PropTypes = require('prop-types');
3029
React = require('react');
3130
ReactDOMClient = require('react-dom/client');
32-
ReactDOMServer = require('react-dom/server');
3331
ReactTestUtils = require('react-dom/test-utils');
3432
act = require('internal-test-utils').act;
3533
});
@@ -159,136 +157,6 @@ describe('ReactContextValidator', () => {
159157
expect(componentDidUpdateContext).toEqual({foo: 'def'});
160158
});
161159

162-
// @gate !disableLegacyContext || !__DEV__
163-
it('should check context types', () => {
164-
class Component extends React.Component {
165-
render() {
166-
return <div />;
167-
}
168-
}
169-
Component.contextTypes = {
170-
foo: PropTypes.string.isRequired,
171-
};
172-
173-
expect(() => ReactTestUtils.renderIntoDocument(<Component />)).toErrorDev(
174-
'Warning: Failed context type: ' +
175-
'The context `foo` is marked as required in `Component`, but its value ' +
176-
'is `undefined`.\n' +
177-
' in Component (at **)',
178-
);
179-
180-
class ComponentInFooStringContext extends React.Component {
181-
getChildContext() {
182-
return {
183-
foo: this.props.fooValue,
184-
};
185-
}
186-
187-
render() {
188-
return <Component />;
189-
}
190-
}
191-
ComponentInFooStringContext.childContextTypes = {
192-
foo: PropTypes.string,
193-
};
194-
195-
// No additional errors expected
196-
ReactTestUtils.renderIntoDocument(
197-
<ComponentInFooStringContext fooValue={'bar'} />,
198-
);
199-
200-
class ComponentInFooNumberContext extends React.Component {
201-
getChildContext() {
202-
return {
203-
foo: this.props.fooValue,
204-
};
205-
}
206-
207-
render() {
208-
return <Component />;
209-
}
210-
}
211-
ComponentInFooNumberContext.childContextTypes = {
212-
foo: PropTypes.number,
213-
};
214-
215-
expect(() =>
216-
ReactTestUtils.renderIntoDocument(
217-
<ComponentInFooNumberContext fooValue={123} />,
218-
),
219-
).toErrorDev(
220-
'Warning: Failed context type: ' +
221-
'Invalid context `foo` of type `number` supplied ' +
222-
'to `Component`, expected `string`.\n' +
223-
' in Component (at **)\n' +
224-
' in ComponentInFooNumberContext (at **)',
225-
);
226-
});
227-
228-
// @gate !disableLegacyContext || !__DEV__
229-
it('should check child context types', () => {
230-
class Component extends React.Component {
231-
getChildContext() {
232-
return this.props.testContext;
233-
}
234-
235-
render() {
236-
return <div />;
237-
}
238-
}
239-
Component.childContextTypes = {
240-
foo: PropTypes.string.isRequired,
241-
bar: PropTypes.number,
242-
};
243-
244-
expect(() =>
245-
ReactTestUtils.renderIntoDocument(<Component testContext={{bar: 123}} />),
246-
).toErrorDev(
247-
'Warning: Failed child context type: ' +
248-
'The child context `foo` is marked as required in `Component`, but its ' +
249-
'value is `undefined`.\n' +
250-
' in Component (at **)',
251-
);
252-
253-
expect(() =>
254-
ReactTestUtils.renderIntoDocument(<Component testContext={{foo: 123}} />),
255-
).toErrorDev(
256-
'Warning: Failed child context type: ' +
257-
'Invalid child context `foo` of type `number` ' +
258-
'supplied to `Component`, expected `string`.\n' +
259-
' in Component (at **)',
260-
);
261-
262-
// No additional errors expected
263-
ReactTestUtils.renderIntoDocument(
264-
<Component testContext={{foo: 'foo', bar: 123}} />,
265-
);
266-
267-
ReactTestUtils.renderIntoDocument(<Component testContext={{foo: 'foo'}} />);
268-
});
269-
270-
it('warns of incorrect prop types on context provider', () => {
271-
const TestContext = React.createContext();
272-
273-
TestContext.Provider.propTypes = {
274-
value: PropTypes.string.isRequired,
275-
};
276-
277-
ReactTestUtils.renderIntoDocument(<TestContext.Provider value="val" />);
278-
279-
class Component extends React.Component {
280-
render() {
281-
return <TestContext.Provider value={undefined} />;
282-
}
283-
}
284-
285-
expect(() => ReactTestUtils.renderIntoDocument(<Component />)).toErrorDev(
286-
'Warning: Failed prop type: The prop `value` is marked as required in ' +
287-
'`Context.Provider`, but its value is `undefined`.\n' +
288-
' in Component (at **)',
289-
);
290-
});
291-
292160
// TODO (bvaughn) Remove this test and the associated behavior in the future.
293161
// It has only been added in Fiber to match the (unintentional) behavior in Stack.
294162
// @gate !disableLegacyContext || !__DEV__
@@ -371,8 +239,6 @@ describe('ReactContextValidator', () => {
371239
'Warning: MiddleMissingContext.childContextTypes is specified but there is no ' +
372240
'getChildContext() method on the instance. You can either define getChildContext() ' +
373241
'on MiddleMissingContext or remove childContextTypes from it.',
374-
'Warning: Failed context type: The context `bar` is marked as required ' +
375-
'in `ChildContextConsumer`, but its value is `undefined`.',
376242
]);
377243
expect(childContext.bar).toBeUndefined();
378244
expect(childContext.foo).toBe('FOO');
@@ -699,24 +565,4 @@ describe('ReactContextValidator', () => {
699565
'Warning: ComponentB: Function components do not support contextType.',
700566
);
701567
});
702-
703-
it('should honor a displayName if set on the context type', () => {
704-
const Context = React.createContext(null);
705-
Context.displayName = 'MyContextType';
706-
function Validator() {
707-
return null;
708-
}
709-
Validator.propTypes = {dontPassToSeeErrorStack: PropTypes.bool.isRequired};
710-
711-
expect(() => {
712-
ReactDOMServer.renderToStaticMarkup(
713-
<Context.Provider>
714-
<Context.Consumer>{() => <Validator />}</Context.Consumer>
715-
</Context.Provider>,
716-
);
717-
}).toErrorDev(
718-
'Warning: Failed prop type: The prop `dontPassToSeeErrorStack` is marked as required in `Validator`, but its value is `undefined`.\n' +
719-
' in Validator (at **)',
720-
);
721-
});
722568
});

packages/react/src/__tests__/ReactJSXElementValidator-test.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ describe('ReactJSXElementValidator', () => {
312312
});
313313

314314
// @gate !disableLegacyContext || !__DEV__
315-
it('should warn on invalid context types', () => {
315+
it('should not warn on invalid context types', () => {
316316
class NullContextTypeComponent extends React.Component {
317317
render() {
318318
return <span>{this.props.prop}</span>;
@@ -321,12 +321,7 @@ describe('ReactJSXElementValidator', () => {
321321
NullContextTypeComponent.contextTypes = {
322322
prop: null,
323323
};
324-
expect(() =>
325-
ReactTestUtils.renderIntoDocument(<NullContextTypeComponent />),
326-
).toErrorDev(
327-
'NullContextTypeComponent: context type `prop` is invalid; it must ' +
328-
'be a function, usually from the `prop-types` package,',
329-
);
324+
ReactTestUtils.renderIntoDocument(<NullContextTypeComponent />);
330325
});
331326

332327
it('should warn if getDefaultProps is specified on the class', () => {

0 commit comments

Comments
 (0)