@@ -217,14 +217,43 @@ describe('forwardRef', () => {
217217 ) ;
218218 } ) ;
219219
220- it ( 'should honor a displayName if set on the forwardRef wrapper in warnings ' , ( ) => {
220+ it ( 'should fall back to showing something meaningful if no displayName or name are present ' , ( ) => {
221221 const Component = props => < div { ...props } /> ;
222222
223223 const RefForwardingComponent = React . forwardRef ( ( props , ref ) => (
224224 < Component { ...props } forwardedRef = { ref } />
225225 ) ) ;
226226
227- RefForwardingComponent . displayName = 'Foo' ;
227+ RefForwardingComponent . propTypes = {
228+ optional : PropTypes . string ,
229+ required : PropTypes . string . isRequired ,
230+ } ;
231+
232+ RefForwardingComponent . defaultProps = {
233+ optional : 'default' ,
234+ } ;
235+
236+ const ref = React . createRef ( ) ;
237+
238+ expect ( ( ) =>
239+ ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
240+ ) . toErrorDev (
241+ 'Warning: Failed prop type: The prop `required` is marked as required in ' +
242+ '`ForwardRef`, but its value is `undefined`.' ,
243+ // There's no component stack in this warning because the inner function is anonymous.
244+ // If we wanted to support this (for the Error frames / source location)
245+ // we could do this by updating ReactComponentStackFrame.
246+ { withoutStack : true } ,
247+ ) ;
248+ } ) ;
249+
250+ it ( 'should honor a displayName if set on the forwardRef wrapper in warnings' , ( ) => {
251+ const Component = props => < div { ...props } /> ;
252+
253+ const RefForwardingComponent = React . forwardRef ( ( props , ref ) => (
254+ < Component { ...props } forwardedRef = { ref } />
255+ ) ) ;
256+ RefForwardingComponent . displayName = 'Outer' ;
228257
229258 RefForwardingComponent . propTypes = {
230259 optional : PropTypes . string ,
@@ -241,17 +270,48 @@ describe('forwardRef', () => {
241270 ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
242271 ) . toErrorDev (
243272 'Warning: Failed prop type: The prop `required` is marked as required in ' +
244- '`Foo`, but its value is `undefined`.\n' +
245- ' in Foo (at **)' ,
273+ '`Outer`, but its value is `undefined`.' ,
274+ // There's no component stack in this warning because the inner function is anonymous.
275+ // If we wanted to support this (for the Error frames / source location)
276+ // we could do this by updating ReactComponentStackFrame.
277+ { withoutStack : true } ,
246278 ) ;
247279 } ) ;
248280
249281 it ( 'should honor a displayName in stacks if set on the inner function' , ( ) => {
250282 const Component = props => < div { ...props } /> ;
251283
252284 const inner = ( props , ref ) => < Component { ...props } forwardedRef = { ref } /> ;
253- inner . displayName = 'Foo' ;
285+ inner . displayName = 'Inner' ;
286+ const RefForwardingComponent = React . forwardRef ( inner ) ;
287+
288+ RefForwardingComponent . propTypes = {
289+ optional : PropTypes . string ,
290+ required : PropTypes . string . isRequired ,
291+ } ;
292+
293+ RefForwardingComponent . defaultProps = {
294+ optional : 'default' ,
295+ } ;
296+
297+ const ref = React . createRef ( ) ;
298+
299+ expect ( ( ) =>
300+ ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
301+ ) . toErrorDev (
302+ 'Warning: Failed prop type: The prop `required` is marked as required in ' +
303+ '`ForwardRef(Inner)`, but its value is `undefined`.\n' +
304+ ' in Inner (at **)' ,
305+ ) ;
306+ } ) ;
307+
308+ it ( 'should honor a outer displayName when wrapped component and memo component set displayName at the same time.' , ( ) => {
309+ const Component = props => < div { ...props } /> ;
310+
311+ const inner = ( props , ref ) => < Component { ...props } forwardedRef = { ref } /> ;
312+ inner . displayName = 'Inner' ;
254313 const RefForwardingComponent = React . forwardRef ( inner ) ;
314+ RefForwardingComponent . displayName = 'Outer' ;
255315
256316 RefForwardingComponent . propTypes = {
257317 optional : PropTypes . string ,
@@ -268,8 +328,8 @@ describe('forwardRef', () => {
268328 ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
269329 ) . toErrorDev (
270330 'Warning: Failed prop type: The prop `required` is marked as required in ' +
271- '`ForwardRef(Foo) `, but its value is `undefined`.\n' +
272- ' in Foo (at **)' ,
331+ '`Outer `, but its value is `undefined`.\n' +
332+ ' in Inner (at **)' ,
273333 ) ;
274334 } ) ;
275335
0 commit comments