Reputation: 111
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
Upvotes: 8
Views: 24783
Reputation: 203408
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]);
Upvotes: 10