I'm testing an component who has 2 useEffect inside an component. Each fetch asynchronously some data.
// Pour récupérer les types de Flux
useEffect(() => {
// AbortController permet d'avorter le fetch si le composant se unmount avant l'arrivé de la réponse
const abortController = new AbortController();
getData(abortController.signal, `${BASE_URL}/sesame-recuperer-type-flux`)
.then((info) => {
setTypeFlux(info.typeFlux);
})
.catch((error) => {
if (error.name === "AbortError") return; // si la query a été avorté, ne faits rien
throw error;
});
return () => {
abortController.abort(); // arrete la requete en avortant grace au abortController sur l'unmount
};
}, []);
I always get this type of error:
PASS tests/Table.test.tsx
FAIL tests/Filtres.test.tsx (5.168 s)
● Console
console.error
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at fn (D:\devgit\sesame\front-mfe-gestion-flux\src\components\Filtres.tsx:13:3)
29 | getData(abortController.signal, `${BASE_URL}/sesame-recuperer-organismes`)
30 | .then((info) => {
> 31 | setOrganismes(info.organismes);
| ^
32 | })
33 | .catch((error) => {
34 | if (error.name === "AbortError") return; // si la query a été avorté, ne faits rien
at printWarning (../node_modules/react-dom/cjs/react-dom.development.js:67:30)
PASS tests/Table.test.tsx (12.061 s)
PASS tests/Filtres.test.tsx (13.435 s)
● Console
console.error
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at fn (D:\devgit\sesame\front-mfe-gestion-flux\src\components\Filtres.tsx:13:3)
29 | getData(abortController.signal, `${BASE_URL}/sesame-recuperer-organismes`)
30 | .then((info) => {
> 31 | setOrganismes(info.organismes);
| ^
32 | })
33 | .catch((error) => {
34 | if (error.name === "AbortError") return; // si la query a été avorté, ne faits rien
at printWarning (../node_modules/react-dom/cjs/react-dom.development.js:67:30)
at error (../node_modules/react-dom/cjs/react-dom.development.js:43:5)
at warnAboutUpdateOnUnmountedFiberInDEV (../node_modules/react-dom/cjs/react-dom.development.js:23914:9)
at scheduleUpdateOnFiber (../node_modules/react-dom/cjs/react-dom.development.js:21840:5)
at setOrganismes (../node_modules/react-dom/cjs/react-dom.development.js:16139:5)
at ../src/components/Filtres.tsx:31:9
I think it's something doing with act() and setState() because with AbortController I cancel the request if the component unmount.
I already tried to wrapped things with act() but it has no effect.
This is my test :
let mockedSetRsqlFiltres = jest.fn();
let mockedSetOpenModal = jest.fn();
let mockedCreerRSQL = jest.fn();
describe("affiche les éléments sans problème", () => {
beforeEach(()=>{
render(<Filtres formatColonnes={formatColonnes} setRsqlFiltres={mockedSetRsqlFiltres} setOpenModal={mockedSetOpenModal} creerRSQL={mockedCreerRSQL}/>);
})
it("contient un filtre au début", async () => {
let filtres = await screen.findAllByTestId("filtre");
expect(filtres.length).toBe(1);
});
it("ajoute un filtre quand on clique sur le bouton ajouter", async () => {
let button = await screen.findByRole('button',{name: "Ajouter filtre"});
fireEvent.click(button);
let filtres = await screen.findAllByTestId("filtre");
expect(filtres.length).toBe(2)
});
});
How can I fix this ?
Thanks for your help !