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
The control that react-router gives to choose how to navigate between routes is great.
But after discussing with my co-workers different approaches to route navigation, we agreed in what would be the best UX for most use cases in our application and in general as a default behavior for any route navigation:
The route navigation awaits for a short period of time for the required data to load, if the data loads before a certain maximum time, the route changes with the UI rendered in the final state, and if the data loading takes too long, the route changes with a fallback loading state to continue to await for the data.
This way we handle well both the regular and worst case scenarios:
If the data loading returns fast enough, we don't show any flashing spinners and incomplete UI states, and we render the UI in the final state as intended without any flickering.
If for any reason a data loading takes too long during runtime which would leave the UI frozen, we render a fallback loading state UI until the data finishes loading to give some feedback for the user.
Looking at the documentation for deferring data loading, I understand that the only option supported by the APIs is deciding about deferring or not during implementation time and they are mutually exclusive per promise.
Would it be a good idea to add support with the core API to this type of "dynamic defer" I described above?
If not, I'd like to ask if it is acceptable to make a custom implementation for it, to confirm if I'm not misusing the lib and potentially having issues in the future.
Below I show an implementation of this pattern, I tested it and everything worked fine:
constrouteObject={element: <Page/>,
// ...loader: ({params: { campaignId }})=>{consttimeoutTime=1000;consttimeoutPromise=newPromise((resolve)=>{// fetch or apollo query, etcconstdataFetchPromise=fetch("/bla").then((res)=>res.json());consttimeoutId=setTimeout(()=>{resolve({data: dataFetchPromise});},timeoutTime);dataFetchPromise.then((data)=>{clearTimeout(timeoutId);returnresolve({ data });});});returntimeoutPromise;},};
The implementation of the component mounted by the route would be like:
exportfunctionPage(){const{ data }=useLoaderData();return(<React.Suspense><Awaitresolve={data}><PageContent/></Await></React.Suspense>);}
The component above wraps the page content with React.Suspense and Await to be able use useAsyncValue, but it could receive the data as prop as well:
Even though it seems that the prop resolve from Await was designed to only receive promises, the custom TrackedPromise from the lib to be precise, when the loader resolves with data being a normal JS object, Await works exactly how I need it, without triggering the React.Suspense and directly rendering the children elements.
Is this implementation correct and safe to use?
Looking at the example where the await is decided in runtime it looks like my approach is fine:
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi,
The control that
react-router
gives to choose how to navigate between routes is great.But after discussing with my co-workers different approaches to route navigation, we agreed in what would be the best UX for most use cases in our application and in general as a default behavior for any route navigation:
The route navigation awaits for a short period of time for the required data to load, if the data loads before a certain maximum time, the route changes with the UI rendered in the final state, and if the data loading takes too long, the route changes with a fallback loading state to continue to await for the data.
This way we handle well both the regular and worst case scenarios:
Looking at the documentation for deferring data loading, I understand that the only option supported by the APIs is deciding about deferring or not during implementation time and they are mutually exclusive per promise.
Would it be a good idea to add support with the core API to this type of "dynamic defer" I described above?
If not, I'd like to ask if it is acceptable to make a custom implementation for it, to confirm if I'm not misusing the lib and potentially having issues in the future.
Below I show an implementation of this pattern, I tested it and everything worked fine:
The implementation of the component mounted by the route would be like:
The component above wraps the page content with
React.Suspense
andAwait
to be able useuseAsyncValue
, but it could receive the data as prop as well:Even though it seems that the prop
resolve
fromAwait
was designed to only receive promises, the customTrackedPromise
from the lib to be precise, when the loader resolves withdata
being a normal JS object,Await
works exactly how I need it, without triggering theReact.Suspense
and directly rendering thechildren
elements.Is this implementation correct and safe to use?
Looking at the example where the
await
is decided in runtime it looks like my approach is fine:Should I always wrap the object to be resolved with
defer
?Beta Was this translation helpful? Give feedback.
All reactions