@samitouri / QOS-React / commits / 5dcf93d146

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

Nicole Levy committed Apr 22, 2018 at 08:39 UTC 5dcf93d146ccde90af2c442d6cb32b29efddb46b
2 files changed +39
packages/react-reconciler/src/ReactFiberBeginWork.js
+17
@@ -16,6 +16,7 @@ import type {NewContext} from './ReactFiberNewContext';
16 import type {HydrationContext} from './ReactFiberHydrationContext';
17 import type {FiberRoot} from './ReactFiberRoot';
18 import type {ExpirationTime} from './ReactFiberExpirationTime';
19 +import checkPropTypes from 'prop-types/checkPropTypes';
20
21 import {
22 IndeterminateComponent,
@@ -63,6 +64,8 @@ import {NoWork, Never} from './ReactFiberExpirationTime';
64 import {AsyncMode, StrictMode} from './ReactTypeOfMode';
65 import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt';
66
67 +const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;
68 +
69 let didWarnAboutBadClass;
70 let didWarnAboutGetDerivedStateOnFunctionalComponent;
71 let didWarnAboutStatelessRefs;
@@ -885,6 +888,20 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
888 const newValue = newProps.value;
889 workInProgress.memoizedProps = newProps;
890
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 +
905 let changedBits: number;
906 if (oldProps === null) {
907 // Initial render
packages/react/src/__tests__/ReactContextValidator-test.js
+22
@@ -225,6 +225,28 @@ describe('ReactContextValidator', () => {
225 ReactTestUtils.renderIntoDocument(<Component testContext={{foo: 'foo'}} />);
226 });
227
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 +
250 // TODO (bvaughn) Remove this test and the associated behavior in the future.
251 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
252 it('should warn (but not error) if getChildContext method is missing', () => {