File tree Expand file tree Collapse file tree
packages/react-reconciler/src Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -295,8 +295,26 @@ function commitHookEffectList(
295295 if ( ( effect . tag & mountTag ) !== NoHookEffect ) {
296296 // Mount
297297 const create = effect . create ;
298- const destroy = create ( ) ;
299- effect . destroy = typeof destroy === 'function' ? destroy : null ;
298+ let destroy = create ( ) ;
299+ if ( typeof destroy !== 'function' ) {
300+ if ( __DEV__ ) {
301+ if ( destroy !== null && destroy !== undefined ) {
302+ warningWithoutStack (
303+ false ,
304+ 'useEffect function must return a cleanup function or ' +
305+ 'nothing.%s%s' ,
306+ typeof destroy . then === 'function'
307+ ? ' Promises and useEffect(async () => ...) are not ' +
308+ 'supported, but you can call an async function inside an ' +
309+ 'effect.'
310+ : '' ,
311+ getStackByFiberInDevAndProd ( finishedWork ) ,
312+ ) ;
313+ }
314+ }
315+ destroy = null ;
316+ }
317+ effect . destroy = destroy ;
300318 }
301319 effect = effect . next ;
302320 } while ( effect !== firstEffect ) ;
Original file line number Diff line number Diff line change @@ -51,4 +51,32 @@ describe('ReactHooks', () => {
5151 ] ) ;
5252 expect ( ReactTestRenderer ) . toHaveYielded ( [ 'Did commit: A, B' ] ) ;
5353 } ) ;
54+
55+ it ( 'warns for bad useEffect return values' , ( ) => {
56+ const { useLayoutEffect} = React ;
57+ function App ( props ) {
58+ useLayoutEffect ( ( ) => {
59+ return props . return ;
60+ } ) ;
61+ return null ;
62+ }
63+ let root ;
64+
65+ expect ( ( ) => {
66+ root = ReactTestRenderer . create ( < App return = { 17 } /> ) ;
67+ } ) . toWarnDev ( [
68+ 'Warning: useEffect function must return a cleanup function or ' +
69+ 'nothing.\n' +
70+ ' in App (at **)' ,
71+ ] ) ;
72+
73+ expect ( ( ) => {
74+ root . update ( < App return = { Promise . resolve ( ) } /> ) ;
75+ } ) . toWarnDev ( [
76+ 'Warning: useEffect function must return a cleanup function or ' +
77+ 'nothing. Promises and useEffect(async () => ...) are not supported, ' +
78+ 'but you can call an async function inside an effect.\n' +
79+ ' in App (at **)' ,
80+ ] ) ;
81+ } ) ;
5482} ) ;
You can’t perform that action at this time.
0 commit comments