@@ -204,144 +204,98 @@ describe('forwardRef', () => {
204204 ) ;
205205 } ) ;
206206
207- it ( 'should fall back to showing something meaningful if no displayName or name are present' , ( ) => {
208- const Component = props => < div { ...props } /> ;
209-
210- const RefForwardingComponent = React . forwardRef ( ( props , ref ) => (
211- < Component { ...props } forwardedRef = { ref } />
212- ) ) ;
213-
214- RefForwardingComponent . propTypes = {
215- optional : PropTypes . string ,
216- required : PropTypes . string . isRequired ,
217- } ;
218-
219- RefForwardingComponent . defaultProps = {
220- optional : 'default' ,
221- } ;
222-
223- const ref = React . createRef ( ) ;
224-
225- expect ( ( ) =>
226- ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
227- ) . toErrorDev (
228- 'Warning: Failed prop type: The prop `required` is marked as required in ' +
229- '`ForwardRef`, but its value is `undefined`.' ,
230- // There's no component stack in this warning because the inner function is anonymous.
231- // If we wanted to support this (for the Error frames / source location)
232- // we could do this by updating ReactComponentStackFrame.
233- { withoutStack : true } ,
207+ it ( 'should skip forwardRef in the stack if neither displayName nor name are present' , async ( ) => {
208+ const RefForwardingComponent = React . forwardRef ( function ( props , ref ) {
209+ return [ < span /> ] ;
210+ } ) ;
211+ ReactNoop . render (
212+ < p >
213+ < RefForwardingComponent />
214+ </ p > ,
215+ ) ;
216+ await expect ( async ( ) => {
217+ await waitForAll ( [ ] ) ;
218+ } ) . toErrorDev (
219+ 'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
220+ ' in p (at **)' ,
234221 ) ;
235222 } ) ;
236223
237- it ( 'should honor a displayName if set on the forwardRef wrapper in warnings' , ( ) => {
238- const Component = props => < div { ...props } /> ;
239-
224+ it ( 'should use the inner function name for the stack' , async ( ) => {
240225 const RefForwardingComponent = React . forwardRef ( function Inner ( props , ref ) {
241- < Component { ... props } forwardedRef = { ref } /> ;
226+ return [ < span /> ] ;
242227 } ) ;
243- RefForwardingComponent . displayName = 'Custom' ;
244-
245- RefForwardingComponent . propTypes = {
246- optional : PropTypes . string ,
247- required : PropTypes . string . isRequired ,
248- } ;
249-
250- RefForwardingComponent . defaultProps = {
251- optional : 'default' ,
252- } ;
253-
254- const ref = React . createRef ( ) ;
255-
256- expect ( ( ) =>
257- ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
258- ) . toErrorDev (
259- 'Warning: Failed prop type: The prop `required` is marked as required in ' +
260- '`Custom`, but its value is `undefined`.\n' +
261- ' in Inner (at **)' ,
228+ ReactNoop . render (
229+ < p >
230+ < RefForwardingComponent />
231+ </ p > ,
262232 ) ;
263- } ) ;
264-
265- it ( 'should pass displayName to an anonymous inner component so it shows up in component stacks' , ( ) => {
266- const Component = props => < div { ...props } /> ;
267-
268- const RefForwardingComponent = React . forwardRef ( ( props , ref ) => (
269- < Component { ...props } forwardedRef = { ref } />
270- ) ) ;
271- RefForwardingComponent . displayName = 'Custom' ;
272-
273- RefForwardingComponent . propTypes = {
274- optional : PropTypes . string ,
275- required : PropTypes . string . isRequired ,
276- } ;
277-
278- RefForwardingComponent . defaultProps = {
279- optional : 'default' ,
280- } ;
281-
282- const ref = React . createRef ( ) ;
283-
284- expect ( ( ) =>
285- ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
286- ) . toErrorDev (
287- 'Warning: Failed prop type: The prop `required` is marked as required in ' +
288- '`Custom`, but its value is `undefined`.\n' +
289- ' in Custom (at **)' ,
233+ await expect ( async ( ) => {
234+ await waitForAll ( [ ] ) ;
235+ } ) . toErrorDev (
236+ 'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
237+ ' in Inner (at **)\n' +
238+ ' in p (at **)' ,
290239 ) ;
291240 } ) ;
292241
293- it ( 'should honor a displayName in stacks if set on the inner function' , ( ) => {
294- const Component = props => < div { ...props } /> ;
295-
296- const inner = ( props , ref ) => < Component { ...props } forwardedRef = { ref } /> ;
297- inner . displayName = 'Inner' ;
298- const RefForwardingComponent = React . forwardRef ( inner ) ;
299-
300- RefForwardingComponent . propTypes = {
301- optional : PropTypes . string ,
302- required : PropTypes . string . isRequired ,
242+ it ( 'should use the inner displayName in the stack' , async ( ) => {
243+ const fn = ( props , ref ) => {
244+ return [ < span /> ] ;
303245 } ;
304-
305- RefForwardingComponent . defaultProps = {
306- optional : 'default' ,
307- } ;
308-
309- const ref = React . createRef ( ) ;
310-
311- expect ( ( ) =>
312- ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
313- ) . toErrorDev (
314- 'Warning: Failed prop type: The prop `required` is marked as required in ' +
315- '`ForwardRef(Inner)`, but its value is `undefined`. \n' +
316- ' in Inner (at **)' ,
246+ fn . displayName = 'Inner' ;
247+ const RefForwardingComponent = React . forwardRef ( fn ) ;
248+ ReactNoop . render (
249+ < p >
250+ < RefForwardingComponent />
251+ </ p > ,
252+ ) ;
253+ await expect ( async ( ) => {
254+ await waitForAll ( [ ] ) ;
255+ } ) . toErrorDev (
256+ 'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n ' +
257+ ' in Inner (at **) \n' +
258+ ' in p (at **)' ,
317259 ) ;
318260 } ) ;
319261
320- it ( 'should honor a outer displayName when wrapped component and memo component set displayName at the same time.' , ( ) => {
321- const Component = props => < div { ...props } /> ;
322-
323- const inner = ( props , ref ) => < Component { ...props } forwardedRef = { ref } /> ;
324- inner . displayName = 'Inner' ;
325- const RefForwardingComponent = React . forwardRef ( inner ) ;
262+ it ( 'can use the outer displayName in the stack' , async ( ) => {
263+ const RefForwardingComponent = React . forwardRef ( ( props , ref ) => {
264+ return [ < span /> ] ;
265+ } ) ;
326266 RefForwardingComponent . displayName = 'Outer' ;
267+ ReactNoop . render (
268+ < p >
269+ < RefForwardingComponent />
270+ </ p > ,
271+ ) ;
272+ await expect ( async ( ) => {
273+ await waitForAll ( [ ] ) ;
274+ } ) . toErrorDev (
275+ 'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
276+ ' in Outer (at **)\n' +
277+ ' in p (at **)' ,
278+ ) ;
279+ } ) ;
327280
328- RefForwardingComponent . propTypes = {
329- optional : PropTypes . string ,
330- required : PropTypes . string . isRequired ,
331- } ;
332-
333- RefForwardingComponent . defaultProps = {
334- optional : 'default' ,
281+ it ( 'should prefer the inner to the outer displayName in the stack' , async ( ) => {
282+ const fn = ( props , ref ) => {
283+ return [ < span /> ] ;
335284 } ;
336-
337- const ref = React . createRef ( ) ;
338-
339- expect ( ( ) =>
340- ReactNoop . render ( < RefForwardingComponent ref = { ref } optional = "foo" /> ) ,
341- ) . toErrorDev (
342- 'Warning: Failed prop type: The prop `required` is marked as required in ' +
343- '`Outer`, but its value is `undefined`.\n' +
344- ' in Inner (at **)' ,
285+ fn . displayName = 'Inner' ;
286+ const RefForwardingComponent = React . forwardRef ( fn ) ;
287+ RefForwardingComponent . displayName = 'Outer' ;
288+ ReactNoop . render (
289+ < p >
290+ < RefForwardingComponent />
291+ </ p > ,
292+ ) ;
293+ await expect ( async ( ) => {
294+ await waitForAll ( [ ] ) ;
295+ } ) . toErrorDev (
296+ 'Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
297+ ' in Inner (at **)\n' +
298+ ' in p (at **)' ,
345299 ) ;
346300 } ) ;
347301
0 commit comments