When using something like a simple custom fetch hook:
import { useEffect, useState } from "react";
import useAxiosPrivate from "./useAxiosPrivate";
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const axiosPrivate = useAxiosPrivate();
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const res = await axiosPrivate.get(url);
setData(res?.data);
}
catch(e) {
setError(e);
}
finally {
setLoading(false);
}
};
fetchData();
},[url]);
return { data, loading, error };
}
export default useFetch;
and then calling it inside of a component:
import { useNavigate } from "react-router-dom";
import useFetch from "/hooks/useFetch";
import Loading from "/components/Loading";
import Movie from "/components/movie/Movie";
const MovieList = () => {
const { data, loading } = useFetch("/api/movies");
const navigate = useNavigate();
const onClick = (id) => {
navigate(/movies/${id});
};
return (
<div>
<ol>
{
loading ?
<Loading /> :
data.map((movie) => {
return (
<Movie key={movie.id} movie={movie} onClick={onClick} />
);
})
}
</ol>
</div>
);
};
export default MovieList;
should you put the deconstructed data into it's own state in any scenarios? I just recently ran into a moment where I want to mutate a list that is created with the data and wasn't sure if it is okay to do something like splicing it directly or if I should instead put it into it's own state.
const ActorList = () => {
const { data, loading } = useFetch("/api/actors");
const [actorDelete, setActorDelete] = useState({});
const [deleteModalOpen, setDeleteModalOpen] = useState(false);
const axiosPrivateDelete = useAxiosPrivateDelete();
const navigate = useNavigate();
const onDeleteModal = (e) => {
e.preventDefault();
setDeleteModalOpen(!deleteModalOpen);
};
const onClick = (id) => {
navigate(/actors/${id});
};
const onDelete = (actor) => {
setActorDelete(actor);
setDeleteModalOpen(!deleteModalOpen);
};
const deleteActor = async (actor) => {
const index = data.indexOf(actor);
await axiosPrivateDelete(api/actors/${actor.id});
// Should data be in state for this?
data.splice(index, 1);
setActorDelete({});
setDeleteModalOpen(false);
};
return (
<>
<ol>
{
loading ?
<Loading /> :
data.map((actor) => {
return (
<Actor key={actor.id} actor={actor} onClick={onClick} onDelete={onDelete} />
);
})
}
</ol>
{
deleteModalOpen &&
<Modal onModal={onDeleteModal}>
<section className="delete-modal">
<p>
Are you sure you want to delete {actorDelete.firstName} {actorDelete.lastName}?
</p>
<Button title="Delete" onClick={() => deleteActor(actorDelete)} />
<Button title="Cancel" onClick={() => setDeleteModalOpen(false)} />
</section>
</Modal>
}
</>
);
};
export default ActorList;
In the above, in deleteActor where I splice data is where I am curious if it should instead be in state or if this is okay.