diff --git a/packages/react/src/ReactElementValidator.js b/packages/react/src/ReactElementValidator.js index 8b03c3a92ae7..c38897ac139b 100644 --- a/packages/react/src/ReactElementValidator.js +++ b/packages/react/src/ReactElementValidator.js @@ -197,7 +197,9 @@ function validatePropTypes(element) { ) { // ForwardRef const functionName = type.render.displayName || type.render.name || ''; - name = functionName !== '' ? `ForwardRef(${functionName})` : 'ForwardRef'; + name = + type.displayName || + (functionName !== '' ? `ForwardRef(${functionName})` : 'ForwardRef'); propTypes = type.propTypes; } else { return; diff --git a/packages/react/src/__tests__/forwardRef-test.js b/packages/react/src/__tests__/forwardRef-test.js index 277f87fd9fe8..82e096e57341 100644 --- a/packages/react/src/__tests__/forwardRef-test.js +++ b/packages/react/src/__tests__/forwardRef-test.js @@ -181,4 +181,33 @@ describe('forwardRef', () => { {withoutStack: true}, ); }); + + it('should honor a displayName if set on the forwardRef wrapper in warnings', () => { + const Component = props =>
; + + const RefForwardingComponent = React.forwardRef((props, ref) => ( + + )); + + RefForwardingComponent.displayName = 'Foo'; + + RefForwardingComponent.propTypes = { + optional: PropTypes.string, + required: PropTypes.string.isRequired, + }; + + RefForwardingComponent.defaultProps = { + optional: 'default', + }; + + const ref = React.createRef(); + + expect(() => + ReactNoop.render(), + ).toWarnDev( + 'Warning: Failed prop type: The prop `required` is marked as required in ' + + '`Foo`, but its value is `undefined`.\n' + + ' in Foo (at **)', + ); + }); }); diff --git a/packages/shared/getComponentName.js b/packages/shared/getComponentName.js index 18793dc5feb3..e39a6965e02e 100644 --- a/packages/shared/getComponentName.js +++ b/packages/shared/getComponentName.js @@ -66,9 +66,10 @@ function getComponentName(type: mixed): string | null { case REACT_FORWARD_REF_TYPE: const renderFn = (type.render: any); const functionName = renderFn.displayName || renderFn.name || ''; - return functionName !== '' - ? `ForwardRef(${functionName})` - : 'ForwardRef'; + return ( + (type: any).displayName || + (functionName !== '' ? `ForwardRef(${functionName})` : 'ForwardRef') + ); } if (typeof type.then === 'function') { const thenable: Thenable = (type: any);