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
This commit is contained in:
Nicole Levy
2018-04-22 08:39:38 -04:00
committed by Dan Abramov
parent c040bcbea8
commit 5dcf93d146
2 changed files with 39 additions and 0 deletions

View File

@@ -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,
@@ -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;
@@ -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

View File

@@ -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', () => {