Skip to content

Commit

Permalink
Validate props on context providers (#12658)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
wherestheguac authored and gaearon committed Apr 22, 2018
1 parent c040bcb commit 5dcf93d
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
17 changes: 17 additions & 0 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {NewContext} from './ReactFiberNewContext';
import type {HydrationContext} from './ReactFiberHydrationContext';
import type {FiberRoot} from './ReactFiberRoot';
import type {ExpirationTime} from './ReactFiberExpirationTime';
import checkPropTypes from 'prop-types/checkPropTypes';

import {
IndeterminateComponent,
Expand Down Expand Up @@ -63,6 +64,8 @@ import {NoWork, Never} from './ReactFiberExpirationTime';
import {AsyncMode, StrictMode} from './ReactTypeOfMode';
import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt';

const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;

let didWarnAboutBadClass;
let didWarnAboutGetDerivedStateOnFunctionalComponent;
let didWarnAboutStatelessRefs;
Expand Down Expand Up @@ -885,6 +888,20 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
const newValue = newProps.value;
workInProgress.memoizedProps = newProps;

if (__DEV__) {
const providerPropTypes = workInProgress.type.propTypes;

if (providerPropTypes) {
checkPropTypes(
providerPropTypes,
newProps,
'prop',
'Context.Provider',
getCurrentFiberStackAddendum,
);
}
}

let changedBits: number;
if (oldProps === null) {
// Initial render
Expand Down
22 changes: 22 additions & 0 deletions packages/react/src/__tests__/ReactContextValidator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,28 @@ describe('ReactContextValidator', () => {
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 />;
}
}

expect(() => ReactTestUtils.renderIntoDocument(<Component />)).toWarnDev(
'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.
it('should warn (but not error) if getChildContext method is missing', () => {
Expand Down

0 comments on commit 5dcf93d

Please sign in to comment.