I am trying to write a very generic abortController hook for a dummy react app. I am trying to use useRef
as it keeps its state across renders. This is how my hook looks like
import { useRef, useEffect } from "react";
export default function useAbortController() {
const abortControllerRef = useRef<AbortController>(new AbortController());
useEffect(() => {
abortControllerRef.current = new AbortController();
return () => {
abortControllerRef.current.abort();
};
});
return abortControllerRef.current;
}
And this is where I am using it.
import { useState } from "preact/hooks";
import Loader from "../../components/Loader/index";
import Search from "../../components/Search";
import useAbortController from "../../hooks/useAbortController";
import todoRepo from "../../repos/todo";
export default function Home() {
const [{ todo, loading, error }, setState] = useState({
todo: null,
loading: false,
error: null,
});
const { signal } = useAbortController();
const { getTodoById } = todoRepo(signal);
const fetchTodo = (id: string) => {
setState({ loading: true, todo: null, error: null });
getTodoById(id)
.then((data) => {
setState({ loading: false, todo: data, error: null });
})
.catch((err: Error) => {
setState({ loading: false, todo: null, error: error.message });
});
};
return (
<>
{loading && <Loader />}
<br />
{error && <h4>{error}</h4>}
<br />
{!loading && todo && (
<>
<h1>{todo.title}</h1>
<h2>{todo.id}</h2>
</>
)}
<br />
<Search onChange={fetchTodo} />
</>
);
}
Strangely on first render and first input everything works as expected. But the aborted controller for some reason does not reset back into a new abortController but I can’t seem to figure out why.