Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate props on context providers #12658

Merged
merged 17 commits into from Apr 22, 2018

Conversation

wherestheguac
Copy link
Contributor

@wherestheguac wherestheguac commented Apr 20, 2018

Description

Prop types aren’t being checked on context providers, resulting in no dev warning in situations like the following:

38910612-fe7cc032-427e-11e8-92dd-568849ccb4b3

References issue: #12636

Changes

  • Added checkPropTypes call to updateContextProvider
  • Added a test to make sure prop types are being checked on providers

Notes

I only added one test as I thought multiple tests with different propType specification would just be testing the underlying prop-types library instead of react. If this needs to be moved or I’ve missed something let me know! 😄

@pull-bot
Copy link

pull-bot commented Apr 20, 2018

Details of bundled changes.

Comparing: 999b656...79ea1b5

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js +0.1% 0.0% 609.63 KB 609.94 KB 140.53 KB 140.59 KB UMD_DEV
react-dom.development.js +0.1% 0.0% 594 KB 594.31 KB 136.37 KB 136.43 KB NODE_DEV
ReactDOM-dev.js +0.1% 0.0% 618.41 KB 618.78 KB 139.14 KB 139.19 KB FB_WWW_DEV

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.1% -0.2% 412.73 KB 413.04 KB 89.59 KB 89.45 KB UMD_DEV
react-art.development.js +0.1% +0.1% 338.56 KB 338.87 KB 70.81 KB 70.87 KB NODE_DEV
ReactART-dev.js +0.1% +0.1% 346.81 KB 347.18 KB 70.42 KB 70.47 KB FB_WWW_DEV

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer.development.js +0.1% -0.2% 345.69 KB 346 KB 72.47 KB 72.33 KB UMD_DEV
react-test-renderer.development.js +0.1% +0.1% 336.51 KB 336.83 KB 69.66 KB 69.72 KB NODE_DEV
ReactTestRenderer-dev.js +0.1% +0.1% 344.98 KB 345.35 KB 69.31 KB 69.37 KB FB_WWW_DEV

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.1% +0.1% 316.9 KB 317.21 KB 65.12 KB 65.18 KB NODE_DEV
react-reconciler-persistent.development.js +0.1% +0.1% 316.23 KB 316.55 KB 64.88 KB 64.94 KB NODE_DEV

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js +0.1% +0.1% 456.63 KB 457 KB 97.38 KB 97.43 KB RN_FB_DEV
ReactNativeRenderer-dev.js +0.1% +0.1% 456.38 KB 456.75 KB 97.32 KB 97.37 KB RN_OSS_DEV
ReactFabric-dev.js +0.1% +0.1% 439.04 KB 439.42 KB 92.94 KB 92.99 KB RN_FB_DEV
ReactFabric-dev.js +0.1% +0.1% 439.08 KB 439.45 KB 92.96 KB 93.01 KB RN_OSS_DEV

Generated by 🚫 dangerJS

workInProgress.type.propTypes,
newProps,
'prop',
'ReactProvider',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s call this Context.Provider

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

newProps,
'prop',
'Context.Provider',
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing the component stack argument. Can you please add it, similar to how we do elsewhere?

I think you can use getCurrentFiberStackAddendum similar to how we do in ReactDOMFiberComponent.js.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhhh I meant to do this after I was done testing it and completely forgot, I’ll get on that tonight!

@@ -885,6 +886,15 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
const newValue = newProps.value;
workInProgress.memoizedProps = newProps;

if (__DEV__) {
checkPropTypes(
workInProgress.type.propTypes,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's only call checkPropTypes if workInProgress.type.propTypes exists. Read it before the call and then, if it exists, call the function, passing it as an argument.

@wherestheguac
Copy link
Contributor Author

@gaearon fixed those issues 😃

@@ -885,6 +891,18 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
const newValue = newProps.value;
workInProgress.memoizedProps = newProps;

const providerPropTypes = workInProgress.type.propTypes;

if (__DEV__ && providerPropTypes) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please split this into two nested conditions? We try to always keep if (__DEV__) { as a separate block to make it very distinctive.

ReactTestUtils.renderIntoDocument(<TestContext.Provider />),
).toWarnDev(
'Warning: Failed prop type: The prop `value` is marked as required in ' +
'`Context.Provider`, but its value is `undefined`.',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please include stack in the expected message. You’ll want to use ** placeholders similar to other tests that assert about the warning with stacks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m having a bit of trouble finding an example of this in the tests. Potentially just not sure what I’m looking for. Do you know of one that uses this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let didWarnAboutBadClass;
let didWarnAboutGetDerivedStateOnFunctionalComponent;
let didWarnAboutStatelessRefs;
let getStack = emptyFunction.thatReturns('');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getStack would only ever be called in DEV, so we can pass getCurrentFiberStackAddendum to checkPropTypes directly and avoid the getStack variable altogether.

@@ -885,6 +886,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;
const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this right after imports so we only do this once. You can check how we do this in other files.

@gaearon
Copy link
Collaborator

gaearon commented Apr 22, 2018

Looks good, thanks!

@gaearon gaearon merged commit 5dcf93d into facebook:master Apr 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants