I'm trying to update a state inside a useEffect
, I'm getting:
React Hook
useEffect
has a missing dependency: 'user'. Either include it or remove the dependency array. You can also do a functional update 'setUser(u => ...)' if you only need 'user' in the 'setUser' call react-hooks/exhaustive-deps
If I put user state as a dependency then I get an infinite loop.
const [user, setUser] = useState({
displayName: '',
hasPassword: false,
...
});
let { userId } = useParams();
useEffect(() => {
const checkPassword = async (userId) => {
try {
const res = await UserService.checkPassword(userId);
if (res.status === 200) {
setUser({...user, hasPassword: res.data.hasPassword });
}
} catch (err) {
setUser({...user, hasPassword: false });
}
};
checkPassword(userId);
}, [userId, user]);
If I remove user from dependency array than everything works fine, but I'm trying to get rid of that warning. I just need to execute this function only once.
I guess you can use the previous state of the user
instead of the state user
as:
setUser(prevState => ({
...prevState,
hasPassword: res.data.hasPassword
}));
Thus you don't need user
in the dependency array.
Final code would be with the suggestion:
useEffect(() => {
const checkPassword = async (userId) => {
try {
const res = await UserService.checkPassword(userId);
if (res.status === 200) {
setUser(prevState => ({
...prevState,
hasPassword: res.data.hasPassword
}));
}
} catch (err) {
setUser(prevState => ({
...prevState,
hasPassword: false
}));
}
};
checkPassword(userId);
}, [userId]);
The method returned on the second position from useState
also accepts a callback, so your code could be rewritten as this:
const [user, setUser] = useState({
displayName: '',
hasPassword: false,
...
});
let { userId } = useParams();
useEffect(() => {
const checkPassword = async (userId) => {
try {
const res = await UserService.checkPassword(userId);
if (res.status === 200) {
setUser(user=>({...user, hasPassword: res.data.hasPassword }));
}
} catch (err) {
setUser(user=>({...user, hasPassword: false }));
}
};
checkPassword(userId);
}, [userId]);
您可以使用 setState 回调语法:
setUser(user => ({ ...user, hasPassword: whatever }))
Since you have circular dependancy ie
user
object changesuser
object againNote that, reference of your user
object changes on every setUser
call, that's why there's infinite loop.
I wouldn't recommend having user
in your dependancy array as you could update user
details if userId
changes.
If still you can't remove
user
dependancy, you could useJSON.stringify(user)
as dependancy instead as the effect would run only when stringified representation of youruser
object changes.
useEffect(() => {
// your effect code
}, [userId, JSON.stringify(user)]);
Note: Use stringify()
only if you don't have values with undefined/NaN etc as the keys would be lost after conversion.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.