I am using a custom useFetch function, the isLoading function is working if the window reloads but when i change the state with useState hooks, the custom hooks works but isLoading is not working.
-
const [url, setUrl] = useState('/api')
const [name, setName] = useState("random");
const filterChoice = (e) => {
const value = document.getElementById('filter').value;
setUrl(`/top/${value}`)
setName(value)
}
const { data: anime, error, isLoading, total } = useFetch(url)
<select name="sort" className='sort' id="filter" onChange={filterChoice}>
<option value="random">filter</option>
<option value="airing">Top Airing</option>
<option value="upcoming">Top Upcoming</option>
<option value="popularity">Top By popularity</option>
</select>
useFetch
import { useState, useEffect } from 'react';
const useFetch = (url) => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [total, setTotal] = useState(0)
useEffect(() => {
const abortCont = new AbortController();
fetch(url)
.then((res) => {
if (!res.ok) {
throw Error('could not fetch the data for that resource')
} else {
return res.json()
}
})
.then((data) => {
if (data.length === 0) {
throw Error('no anime available')
}
setData(data)
setTotal(data.length)
setIsLoading(false)
setError(null)
})
.catch((err) => {
if (err.name === 'AbortError') {
console.log('Fetch aborted')
}
setIsLoading(false)
setError(err.message)
})
return () => abortCont.abort()
},[url])
return {data,isLoading,error,total}
}
export default useFetch;
Inside useEffect
, before making the fetch call, you have to reset the isLoading
state value. Have modified the code. Let me know if it works.
import { useState, useEffect } from 'react';
const useFetch = (url) => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [total, setTotal] = useState(0)
useEffect(() => {
const abortCont = new AbortController();
setIsLoading(true); // This line was missing
fetch(url)
.then((res) => {
if (!res.ok) {
throw Error('could not fetch the data for that resource')
} else {
return res.json()
}
})
.then((data) => {
if (data.length === 0) {
throw Error('no anime available')
}
setData(data)
setTotal(data.length)
setIsLoading(false)
setError(null)
})
.catch((err) => {
if (err.name === 'AbortError') {
console.log('Fetch aborted')
}
setIsLoading(false)
setError(err.message)
})
return () => abortCont.abort()
},[url])
return {data,isLoading,error,total}
}
export default useFetch;