Infinite loop with useLazyAxio
Closed this issue · 2 comments
HI, I made a simple example to reproduce the bug : https://codesandbox.io/s/pensive-sky-0zhv5
I have an accordion and I would like to load its content only when the accordion is open.
So, to do that I call the getData
from the useLazyAxios
inside an useEffect
hook and it causes an infinite loop.
I don't know if I miss something or this is a bug ?
Here is the code
import React from "react";
import ReactDOM from "react-dom";
import axios from "axios";
import { useLazyAxios } from "use-axios-client";
import "./styles.css";
const instance = axios.create({
withCredentials: true
});
function App() {
const [open, setOpen] = React.useState(false);
const [getData, { data, loading, cancel }] = useLazyAxios({
url: "https://jsonplaceholder.typicode.com/todos/",
axiosInstance: instance
});
React.useEffect(() => {
if (open && !loading) {
console.log("getData");
getData();
}
}, [getData, open, loading]);
return (
<details open={open}>
<summary onClick={() => setOpen(oldValue => !oldValue)}>
Click to toggle accordion
</summary>
<div>
{!loading && data && (
<h2>Load the data only if the accordion is open</h2>
)}
</div>
</details>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Appreciate the repro case. So I see three separate issues here - the first one is in the useEffect
body:
React.useEffect(() => {
if (open && !loading) {
console.log("getData");
getData();
}
}, [getData, open, loading]);
I don't think you want to call getData
when loading
is false
, because that means as soon as the request completes, it will be retriggered again (and again).
For clarity, this will happen:
- Accordion is opened
useEffect
function is triggeredgetData
is called andloading
is set totrue
- Network request completes and
loading
is set tofalse
- Steps 2-4 loop
I think what you actually want is:
React.useEffect(() => {
if (open) {
console.log("getData");
getData();
}
}, [getData, open]);
However, there is a separate second issue here that could be considered a bug in use-axios-client
- since getData
is not memoized with useCallback
, it cannot be passed as a dependency to useEffect
, as it gets freshly created on every render. This has been fixed and is now available in v1.0.1.
The last issue is related to the <details>
HTML element open state getting out of sync with your local component open
state, which you can find some more details on in this thread.
Updated your codesandbox using use-axios-client@v1.0.1: https://codesandbox.io/s/festive-glade-imxd6
Let me know if you have any other issues. Appreciate the help!
@zakangelle thank you very much for the new version which solvles the bug, I remove the loading dependency too.
For the accordion bug, you absolutely right, we have to put e.preventDefault()
to synchro the component with its react state.