Handling Loading States in React
If you are working with our React integration you may need to show when a component it's fetching data from the API. By default our useResource and useCollection hooks use Suspense, this means the fetching promise is thrown and the parent of your component could control the loading state.
Let's imagine we have a User component which will fetch the user with an ID received as a prop and render the full name of that user.
import React from 'react';import { useResource } from 'coreql';
function User({ id }) { const { data: user } = useResource('users', id, { format: 'denormalized' }); return <h1>{user?.fullName}</h1>;}
export default User;Now let's create a parent component that will render the user, it will have a state to keep the ID and let the user of the app change it.
function App() { const [id, setId] = React.useState(1);
return ( <> <input type="text" value={id} onChange={event => setId(event.target.value)} /> <User id={id} /> </> );}If we run that it will throw an error, since it will try to load the user with ID 1, to solve this error we need to wrap our User component in the Suspense boundaries.
function App() { const [id, setId] = React.useState(1);
return ( <> <input type="text" value={id} onChange={event => setId(event.target.value)} /> <React.Suspense fallback={<p>Loading...</p>}> <User id={id} /> </React.Suspense> </> );}Now every time we change the resource it will fetch it and show the Loading... message we defined in the Suspense boundary.
Additionally, CoreQL exposes an SSRSuspense component which will render your fallback when doing Server-Side Rendering, we recommend you to use it if you are using Next.js or manually implementing SSR in your React application.
function App() { const [id, setId] = React.useState(1);
return ( <> <input type="text" value={id} onChange={event => setId(event.target.value)} /> <SSRSuspense fallback={<p>Loading...</p>}> <User id={id} /> </SSrSuspense> </> );}The props received by SSRSuspense are the same as React.Suspense and extend from those so they will always be up to date with any new prop.
Final Code
// user.jsimport React from 'react';import { useResource } from 'coreql';
function User({ id }) { const { data: user } = useResource('users', id, { format: 'denormalized' }); return <h1>{user?.fullName}</h1>;}
export default User;// index.jsimport React from 'react';import { SSRSuspense } from 'coreql';import User from './user';
function App() { const [id, setId] = React.useState(1);
return ( <> <input type="text" value={id} onChange={event => setId(event.target.value)} /> <SSRSuspense fallback={<p>Loading...</p>}> <User id={id} /> </SSrSuspense> </> );}