You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importReactfrom'react';functionTimestamp(){const[now,setNow]=React.useState(Date.now());React.useEffect(()=>{consttimer=setInterval(()=>{// when the app is frozen every update here appears to abort the render and restart it,// meaning the component never completes the transition from unuspended -> suspendedsetNow(Date.now());},// if you make this interval high enough then the app doesn't// freeze as it manages to suspend before the state update// interrupts it0);return()=>clearInterval(timer);},[]);return<div>Timestamp: {now} (should not freeze)</div>;}constfakeLoading=newPromise((resolve)=>{setTimeout(()=>{fakeLoading.done=true;console.log('loaded');resolve();},5000);});functionuseRemoteData(){if(!fakeLoading.done){// suspend!throwfakeLoading;}return'the data';}functionSomeRemoteData(){constdata=useRemoteData();return<div>Data: {data}</div>;}functionFallback(){React.useEffect(()=>{// this never happens as it appears it never manages to suspendconsole.log('===> Fallback mount');return()=>console.log(' <=== Fallback unmount');});// ... but it is constantly attempting renders// console.log("Fallback render")return<div>Suspended: Yes</div>;}exportdefaultfunctionApp(){// Change the initial state to `true` and there is no issue// The problem seems to occur when going from unsuspended -> suspended,// and not when starting suspenededconst[showRemoteData,setShowRemoteData]=React.useState(false);React.useEffect(()=>{setShowRemoteData(true);},[]);return(<div><Timestamp/><React.Suspensefallback={// expecting to this to render when `showRemoteData` goes to `true`<Fallback/>}><div>Suspended: No</div>{showRemoteData&&<SomeRemoteData/>}</React.Suspense></div>);}
index.js
importReact,{StrictMode}from'react';import{createRoot}from'react-dom/client';importAppfrom'./App';constrootElement=document.getElementById('root');constroot=createRoot(rootElement);// strict mode disabled just to make the console logs clearerroot.render(// <StrictMode><App/>// </StrictMode>);
The current behavior
When the fallback should be rendered the app gets stuck in a rendering loop and the fallback is never actually mounted. You can see the timestamp stops updating.
Screen.Recording.2024-05-15.at.14.09.22.mov
The expected behavior
The fallback should be rendered whilst the loading is happening, and the timestamp should keep updating.
Note this is working in react 19 🎉 but would be great to get a patch for 18 in the meantime.
React version: 18.1.0
Steps To Reproduce
Run https://stackblitz.com/edit/react-ufudqb?file=src%2FApp.js
Link to code example: https://stackblitz.com/edit/react-ufudqb?file=src%2FApp.js
app.js
index.js
The current behavior
When the fallback should be rendered the app gets stuck in a rendering loop and the fallback is never actually mounted. You can see the timestamp stops updating.
Screen.Recording.2024-05-15.at.14.09.22.mov
The expected behavior
The fallback should be rendered whilst the loading is happening, and the timestamp should keep updating.
Note this is working in react 19 🎉 but would be great to get a patch for 18 in the meantime.
Also this may be related to #27161
Thanks
The text was updated successfully, but these errors were encountered: