I am making an api call from useEffect
hook
function ChangePassword(props) {
const token = props.match.params.token;
const [state, setState] = useState({
password: "",
confirmPassword: "",
});
const [status, setStatus] = useState({
loaded: false,
auth: false,
});
useEffect(() => {
let { auth } = status;
axios
.get(
`http://localhost:2606/api/hostler/changepassword?token=${token}`
)
.then((res) => {
console.log("res", res);
auth = res.status === 202;
})
.then(() => setStatus({ auth, loaded: true }))
.catch((err) => console.log("err", err));
},[]);
return (
// code
);
}
But react gives warning
React Hook useEffect has missing dependencies: 'status' and 'token'. Either include them or remove the dependency array react-hooks/exhaustive-deps
also adding status
to dependency array will result in an infinite loop because setStatus
is called inside of useEffect
If you want the effect to run only once when the component mounts then it is technically correct to specify an empty dependency array. However, the React-hooks linting rules aren't able to differentiate this case. You can disable the rule specifically for that line.
I notice also that your effect doesn't really have a dependency on status.auth
since you are always mutating/overwriting it anyway, you can remove it and just set the new auth
state value.
useEffect(() => {
axios
.get(
`http://localhost:2606/api/hostler/changepassword?token=${token}`
)
.then((res) => {
console.log("res", res);
setStatus({ auth: res.status === 202, loaded: true })
})
.then(() => )
.catch((err) => console.log("err", err));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
However, disabling the rule will possibly mask future updates, so you'll want to include token
as a dependency. If the component rerenders/remounts and the token has changed you'll want to ensure you are working with the latest values. In other words, you don't want to use stale state/prop values.
useEffect(() => {
axios
.get(
`http://localhost:2606/api/hostler/changepassword?token=${token}`
)
.then((res) => {
console.log("res", res);
setStatus({ auth: res.status === 202, loaded: true })
})
.then(() => )
.catch((err) => console.log("err", err));
}, [token]);
If you want to only run the GET request when auth
is false then it would be a dependency and should be included. And so you don't render loop if res.status === 202
resolves false, also include a condition that you haven't completed loading yet.
useEffect(() => {
!auth && !loaded && axios
.get(
`http://localhost:2606/api/hostler/changepassword?token=${token}`
)
.then((res) => {
console.log("res", res);
setStatus({ auth: res.status === 202, loaded: true })
})
.then(() => )
.catch((err) => console.log("err", err));
}, [auth, loaded, token]);