Reputation: 13830
I have created a React application that fetches a list of clusters from a database and displays it in a grid view. Since, the list of clusters changes very rarily (maybe once a week), I don't want to fetch it every time the user visits /clusters
.
I have tried to change useState
to useRef
, but in both cases clusters
is []
, when the component is re-created (not re-rerendered?)
I'm not sure my terminology is correct, so please correct me, if I'm wrong.
What's the React way of solving this problem?
useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.
App.jsx:
...
<Routes>
<Route path="/" element={<Home />} />
<Route path="/clusters" element={<ClusterList />} />
<Route path="/clusters/:id" element={<ClusterInfo />} />
<Route path="/assets" element={<Assets />} />
</Routes>
...
ClusterList.jsx:
export const ClusterList = () => {
const discoveryApi = useApi(discoveryApiRef);
const authFetch = useAuthFetch();
const [loading, setLoading] = useState<boolean>(false);
const [clusters, setClusters] = useState<Cluster[]>([]);
const fetchClusters = useCallback(async (): Promise<Cluster[]> => {
const url = await discoveryApi.getBaseUrl('containerplatform');
const response = await authFetch(`${url}/clusters`);
return await response.json();
}, [discoveryApi, authFetch]);
useEffect(() => {
(async () => {
try {
setLoading(true);
const _clusters = await fetchClusters();
setClusters(_clusters);
} finally {
setLoading(false);
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fetchClusters]);
...
Upvotes: 0
Views: 31
Reputation: 143
You can't rely on state variables to persist information, you will need to use localStorage or sessionStorage for storing cluster information, in you case using localStorage will suffice.
Example of using localStorage:-
const fetchClusters = useCallback(async (): Promise<Cluster[]> => {
if (!localStorage.getItem('clusters')){
const url = await discoveryApi.getBaseUrl('containerplatform');
const response = await authFetch(`${url}/clusters`);
const clusters = await response.json();
localStorage.setItem('clusters', JSON.stringify(clusters))
}
return JSON.parse(localStorage.getItem('clusters'))
}, [discoveryApi, authFetch]);
Upvotes: 1