Skip to content

Commit 5dcf93d

Browse files
wherestheguacgaearon
authored andcommitted
Validate props on context providers (#12658)
* checkPropTypes in updateContextProvider * invalid “prop” * `type not `types` .. :l * test * don’t need extra check with no spelling mistake (: * change error message to specifically address provider * don’t need class, add extra render to make sure good props go through * nitpicky rename * prettier * switch to `Context.Provider` * add stack to warning, add extra undefined check * separate dev check * add stack to test * more efficient * remove unused function * prettier * const to top
1 parent c040bcb commit 5dcf93d

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {NewContext} from './ReactFiberNewContext';
1616
import type {HydrationContext} from './ReactFiberHydrationContext';
1717
import type {FiberRoot} from './ReactFiberRoot';
1818
import type {ExpirationTime} from './ReactFiberExpirationTime';
19+
import checkPropTypes from 'prop-types/checkPropTypes';
1920

2021
import {
2122
IndeterminateComponent,
@@ -63,6 +64,8 @@ import {NoWork, Never} from './ReactFiberExpirationTime';
6364
import {AsyncMode, StrictMode} from './ReactTypeOfMode';
6465
import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt';
6566

67+
const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;
68+
6669
let didWarnAboutBadClass;
6770
let didWarnAboutGetDerivedStateOnFunctionalComponent;
6871
let didWarnAboutStatelessRefs;
@@ -885,6 +888,20 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
885888
const newValue = newProps.value;
886889
workInProgress.memoizedProps = newProps;
887890

891+
if (__DEV__) {
892+
const providerPropTypes = workInProgress.type.propTypes;
893+
894+
if (providerPropTypes) {
895+
checkPropTypes(
896+
providerPropTypes,
897+
newProps,
898+
'prop',
899+
'Context.Provider',
900+
getCurrentFiberStackAddendum,
901+
);
902+
}
903+
}
904+
888905
let changedBits: number;
889906
if (oldProps === null) {
890907
// Initial render

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,28 @@ describe('ReactContextValidator', () => {
225225
ReactTestUtils.renderIntoDocument(<Component testContext={{foo: 'foo'}} />);
226226
});
227227

228+
it('warns of incorrect prop types on context provider', () => {
229+
const TestContext = React.createContext();
230+
231+
TestContext.Provider.propTypes = {
232+
value: PropTypes.string.isRequired,
233+
};
234+
235+
ReactTestUtils.renderIntoDocument(<TestContext.Provider value="val" />);
236+
237+
class Component extends React.Component {
238+
render() {
239+
return <TestContext.Provider />;
240+
}
241+
}
242+
243+
expect(() => ReactTestUtils.renderIntoDocument(<Component />)).toWarnDev(
244+
'Warning: Failed prop type: The prop `value` is marked as required in ' +
245+
'`Context.Provider`, but its value is `undefined`.\n' +
246+
' in Component (at **)',
247+
);
248+
});
249+
228250
// TODO (bvaughn) Remove this test and the associated behavior in the future.
229251
// It has only been added in Fiber to match the (unintentional) behavior in Stack.
230252
it('should warn (but not error) if getChildContext method is missing', () => {

0 commit comments

Comments
 (0)