Data fetching
-
Colocate your data fetching logic in a file suffixed with
.resource
. For example,user.resource.ts
contains the data fetching logic for the User component. -
Wherever possible, prefer abstracting your data fetching into a custom hook rather than fetching with effects (opens in a new tab). Fetching data with effects has many downsides (opens in a new tab) and should be avoided. Instead, prefer using SWR (opens in a new tab) hooks.
-
Use SWR (opens in a new tab) hooks to fetch data from the backend. Use useSWRImmutable (opens in a new tab) for resources that are not expected to change often, such as concepts or backend configurations.
-
Put the SWR hook in a resource file, and export it as a function. This allows us to reuse the same hook in multiple components.
-
Memoize the return value of your SWR hook using
useMemo
to prevent unnecessary rerenders. This is especially important if the hook is used in a component that is rendered many times, such as a table row. -
Data fetching hooks should follow the naming convention
use<resource>
. For example,useUser
is the hook for fetching user data. -
Use openmrsFetch (opens in a new tab) to fetch data from the backend.
openmrsFetch
is a wrapper around thefetch
API that adds authentication and authorization headers and handles errors. Pass it to SWR hooks as thefetcher
argument. -
Use the
error
,isLoading
,isValidating
andmutate
properties of the SWR hook to handle errors, loading states and mutations. Don't recreate these properties manually. -
Use SWR's conditional data fetching (opens in a new tab) pattern when the request depends on some condition. For example, if the request depends on a prop, only make the request if the prop is true.
// Only fetch user data if userId is provided const url = userId ? `/ws/rest/v1/user/${userId}` : null; const { data, error, isLoading, isValidating, mutate } = useSWR<User>(url, openmrsFetch);