Reactjs Using Usestate Causing Loop Of Axios Requests
Solution 1:
useEffect(() => {
const config = {
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token')
}
}
axios.get('users', config).then((res) => {
if (res.status == 200 && res.data.msg == "success") {
setUsers(res.data.users)
}
else {
history.push("/");
}
feather.replace()
});
}, []);
note here I passed the empty array[]
as the second argument for useEffect,
Reason of empty array at useEffect
If you want to run an effect and clean it up only once (on the mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to be re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.
read more about useEffect
Solution 2:
You would want to add an empty array as useEffect
dependency, so it only run once:
useEffect(() => {
const config = {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
};
axios.get("users", config).then((res) => {
if (res.status == 200 && res.data.msg == "success") {
setUsers(res.data.users);
} else {
history.push("/");
}
feather.replace();
});
}, []); //<-- Add empty dependency here
Solution 3:
The useEffect
hook basically accepts two arguments, the first one being the callback, and the second one is an array of dependencies (optional). The purpose of the second argument (array of dependencies) is to trigger the callback function, whenever any value in the dependencies array change. So, if you don't use the dependencies array in your useEffect
hook, the callback function is executed every time the component is rendered, i.e, whenever the state variables are mutated.
So what's causing the loop?
const [ users, setUsers ] = useState([]);
useEffect(() => {
const config = {
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token')
}
}
axios.get('users', config).then((res) => {
if (res.status == 200 && res.data.msg == "success") {
setUsers(res.data.users) //Updating state causes the component to re-render
}
else {
history.push("/");
}
feather.replace()
});
});
Looking at your code, we can observe that you are using two hooks ( useState
and useEffect
) , so when the promise is resolved, you are updating your users
state with the latest fetched information. So far, so good. When a state is updated, we know that the component is re-rendered (that's the basic principle on how React works). So updating the users
state causes the component function to re-render, which would again invoke useEffect
which would again update users
state, and so forth.
Workaround
To avoid this loop, we'd want to execute useEffect only once, and not every time the component is rendered. This could be accomplished by passing an empty array as the second argument (Which basically tells React to run `useEffect` only when the component is rendered for the first time).const [ users, setUsers ] = useState([]);
useEffect(() => {
const config = {
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token')
}
}
axios.get('users', config).then((res) => {
if (res.status == 200 && res.data.msg == "success") {
setUsers(res.data.users) //Updating state causes the component to re-render
}
else {
history.push("/");
}
feather.replace()
});
},[]); //Empty array as the second argument
This is similar to componentDidMount
when working with class-based components.
Further, you could also add variables to the array that would cause the useEffect
to be invoked only when the variables in the array are mutated.
Solution 4:
Add dependency array to you're useEffect hook , this will solve you're problem
this will act like component did mount
useEffect(()=> {
/// you're code
} , [])
but the one that you used acts like component did update and causes problem because you need to execute the code only when component mounted
Post a Comment for "Reactjs Using Usestate Causing Loop Of Axios Requests"