-
Notifications
You must be signed in to change notification settings - Fork 50.2k
ForwardRefs supports propTypes #12911
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,11 @@ import lowPriorityWarning from 'shared/lowPriorityWarning'; | |
| import describeComponentFrame from 'shared/describeComponentFrame'; | ||
| import isValidElementType from 'shared/isValidElementType'; | ||
| import getComponentName from 'shared/getComponentName'; | ||
| import {getIteratorFn, REACT_FRAGMENT_TYPE} from 'shared/ReactSymbols'; | ||
| import { | ||
| getIteratorFn, | ||
| REACT_FORWARD_REF_TYPE, | ||
| REACT_FRAGMENT_TYPE, | ||
| } from 'shared/ReactSymbols'; | ||
| import checkPropTypes from 'prop-types/checkPropTypes'; | ||
| import warning from 'fbjs/lib/warning'; | ||
|
|
||
|
|
@@ -44,6 +48,14 @@ if (__DEV__) { | |
| return element.type; | ||
| } else if (element.type === REACT_FRAGMENT_TYPE) { | ||
| return 'React.Fragment'; | ||
| } else if ( | ||
| typeof element.type === 'object' && | ||
| element.type !== null && | ||
| element.type.$$typeof === REACT_FORWARD_REF_TYPE | ||
| ) { | ||
| const functionName = | ||
| element.type.render.displayName || element.type.render.name || ''; | ||
| return functionName !== '' ? `ForwardRef(${functionName})` : 'ForwardRef'; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this look like
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's similar. But We could refactor both to use a shared helper, but it didn't seem like the obvious correct thing to do in this case. |
||
| } else { | ||
| return element.type.displayName || element.type.name || 'Unknown'; | ||
| } | ||
|
|
@@ -213,30 +225,39 @@ function validateChildKeys(node, parentType) { | |
| * @param {ReactElement} element | ||
| */ | ||
| function validatePropTypes(element) { | ||
| const componentClass = element.type; | ||
| if (typeof componentClass !== 'function') { | ||
| const type = element.type; | ||
| let name, propTypes; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't it be
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current approach avoids reading |
||
| if (typeof type === 'function') { | ||
| // Class or functional component | ||
| name = type.displayName || type.name; | ||
| propTypes = type.propTypes; | ||
| } else if ( | ||
| typeof type === 'object' && | ||
| type !== null && | ||
| type.$$typeof === REACT_FORWARD_REF_TYPE | ||
| ) { | ||
| // ForwardRef | ||
| const functionName = type.render.displayName || type.render.name || ''; | ||
| name = functionName !== '' ? `ForwardRef(${functionName})` : 'ForwardRef'; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, I feel like this is getting out of hand a little bit. We're going to forget updating some of these.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
😝 We often inline things rather than reuse them. I made a judgement call. I'm happy to change it if you think I should.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Write everything twice. This is three times. :-) |
||
| propTypes = type.propTypes; | ||
| } else { | ||
| return; | ||
| } | ||
| const name = componentClass.displayName || componentClass.name; | ||
| const propTypes = componentClass.propTypes; | ||
| if (propTypes) { | ||
| currentlyValidatingElement = element; | ||
| checkPropTypes(propTypes, element.props, 'prop', name, getStackAddendum); | ||
| currentlyValidatingElement = null; | ||
| } else if ( | ||
| componentClass.PropTypes !== undefined && | ||
| !propTypesMisspellWarningShown | ||
| ) { | ||
| } else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) { | ||
| propTypesMisspellWarningShown = true; | ||
| warning( | ||
| false, | ||
| 'Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', | ||
| name || 'Unknown', | ||
| ); | ||
| } | ||
| if (typeof componentClass.getDefaultProps === 'function') { | ||
| if (typeof type.getDefaultProps === 'function') { | ||
| warning( | ||
| componentClass.getDefaultProps.isReactClassApproved, | ||
| type.getDefaultProps.isReactClassApproved, | ||
| 'getDefaultProps is only used on classic React.createClass ' + | ||
| 'definitions. Use a static property named `defaultProps` instead.', | ||
| ); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's hoist reading
element.typeso we don't keep repeating its reads?