I know this question gets asked a lot, but from the answers I could find I saw:
- either no cleanup function in
useEffect
(so not my use case) - people not using dependencies at all (and a simple
[]
dependency would suffice)
So, here's my code:
import { useEffect, useState } from "react";
import { Button } from "@material-ui/core";
import { CircularProgress } from "@material-ui/core";
export default function App() {
const [tasks, setTasks] = useState<string[]>([]);
useEffect(() => {
const getTasks = () => {
setTasks(["1", "2", "3"]);
};
getTasks();
return () => {
setTasks([]);
};
}, [tasks]);
if (tasks.length === 0) {
return <CircularProgress />;
}
return (
<div>
{JSON.stringify(tasks)}
<Button onClick={() => setTasks([])}>Reset tasks data</Button>
</div>
);
}
CodeSandbox link: here. I removed the tasks
from useEffect
dependencies, because otherwise there's an infinite loop and the browser tab may crash.
Let me explain what I want to achieve. This is just a snippet trying to mimic what I'm working on. I have a page with a table. This table is created by pulling some data from an API. So, the page loads, a table gets rendered. Then, under a table I have an "Add task" button. This brings up a little form to the front, where a new task can be created. I pass an onSubmit
method to it, so when a user clicks "Create", the POST request is made. And then I want the table to be updated.
To do this, I set the tasks
to []
, which are state, so component gets re-rendered, useEffect
kicks in and re-downloads the tasks, which will contain the newly created one. And it works, but only if I don't use a cleanup function in useEffect
. If I do, I enter an infinite loop (because of the tasks
dependency I guess).
As I don't want to put axios
calls in the example, this is the analogy:
getTasks
in my app makes the API call- the button from the example is the button that opens a form to create a new task
- didn't want to add a table to the example, so just to show the data, I
JSON.stringify()
it
Anyway, to the question: I know I need the dependency to make the page refresh when I make the changes (in the example - click the button). How can I achieve what I want (re-render the page after the change to tasks
is made) and retain the cleanup function in useEffect
? (because if I remove it, everything works)