I have a component that fetch data on mount thanks to a useEffect hooks. I'd like it to not refetch data on mount, and instead use the 'cached' data provided by useSwr hooks when i re-navigate to this component. Im not sure how to do this. What i have read is that you can call swr like this :
const { data } = useSwr('same route as previous one')
and it 'll gives you the data stored in cache by the previous swr call.
const CategoryList = ({setLoading}) => {
const [category, setCategory] = useState('');
const [mounted, setMounted] = useState(false);
const [parameters, setParameters] = useState({});
const company_id = localStorage.getItem('company_id')
const session = new SessionService();
const { dataFromFetch, error } = useSWR([mounted ? `${session.domain}/company/${company_id}/category-stats` : null, parameters ], url =>
session.fetch(url, {
method: 'GET',
})
, {
onSuccess: (dataFromFetch) => {
setCategory(dataFromFetch)
setLoading(false)
setMounted(false)
},
onError: (err, key, config) => {
console.log("error", err)
}
}
)
useEffect(() => {
setMounted(true)
setLoading(true)
}, [])
return (
<div className={classes.CategoryList}>
<h5>Parc de véhicules</h5>
<div className={classes.CategoriesCards}>
{category.data? category.data.map((element, index) => {
return <CategoryItem
category={element.data.name}
carNumber={element.stats.nb_vehicles}
locating={element.stats.nb_booked}
available={element.stats.nb_available}
blocked={element.stats.nb_unavailable}
percentage={(element.stats.nb_booked / element.stats.nb_vehicles * 100).toFixed(2)}
key={index}
/>
}): null}
</div>
</div>
)
}
export default CategoryList;
Plus, in an other hand, i'd like my SWR hooks not to consistently try to refetch data like it is dooing actually. What i tried is passing options after my fetcher function, like it is stipulate in this post SWR options explanation. Actually my component is trying to refetch data every 5-10seconds, though unsuccesfully thanks to my 'mounted' condition which result in a 'null' route ( which is the recommended way to do it according to the documentation ). It still sends a request with response 404, which i'd like to avoid.
const [parameters, setParameters] = useState({
revalidateOnFocus: false,
revalidateOnMount:false,
revalidateOnReconnect: false,
refreshWhenOffline: false,
refreshWhenHidden: false,
refreshInterval: 0
});
const company_id = localStorage.getItem('company_id')
const session = new SessionService();
const { dataFromFetch, error } = useSWR([mounted ? `${session.domain}/company/${company_id}/category-stats` : null, parameters ], url =>
session.fetch(url, {
method: 'GET',
})
, {
onSuccess: (dataFromFetch) => {
setCategory(dataFromFetch)
setLoading(false)
setMounted(false)
},
onError: (err, key, config) => {
console.log("error", err)
}
}
)
According to SWR's documentation, the hook's API is
const { data, error, isValidating, mutate } = useSWR(key, fetcher, options)In your code, you're passing the options as part of an array in the first argument, when it should be the third.
A minor refactor shows how it can be fixed:
You've also over-complicated your code quite a bit - there's no need for
onSuccessoronErrorhandlers - you can simply use the returned valuesdataanderrorinstead.Also, no need to save the fetched data to state by using
setCategory. Just read directly fromdata. That's the benefit of of SWR It will auto-magically trigger re-renders when data is fetched.