我使用Redux Toolkit(RTK)Query进行API调用,使用RTK进行状态管理。我面临的问题是,每次登录时,我从后端获得的用户信息不会从localStorage自动更新,并且需要在userSlice
中访问数据之前刷新一次。我使用extraReducers
自动从userLogin
端点获取数据并将其存储在localStorage中。我再次访问localStorage数据并将其作为userSlice
的初始状态提供。
这是我的User Slice。
import { createSlice } from "@reduxjs/toolkit";
import Apiservice from "../service/apiService";
const initialState = {
userInfo: localStorage.getItem("userInfo")
? JSON.parse(localStorage.getItem("userInfo"))
: null,
};
const userSlice = createSlice({
name: "userSlice",
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addMatcher(
Apiservice.endpoints.userLogin.matchFulfilled,
(state, action) => {
localStorage.setItem("userInfo", JSON.stringify(action.payload));
}
);
builder.addMatcher(
Apiservice.endpoints.getMyDetails.matchFulfilled,
(state, action) => {
localStorage.setItem("userInfo", JSON.stringify(action.payload));
}
);
},
});
export const {} = userSlice.actions;
export default userSlice.reducer;
这是Login
组件,我需要手动调用window.location.reload()
-不这样做将不会给我从userSlice
的userInfo
数据。
const Login = () => {
const [showPass, setShowPass] = useState(false);
const [showPass1, setShowPass1] = useState(false);
const {
control,
watch,
register,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues: {
email: "",
password: "",
},
});
const toast = useToast();
const navigate = useNavigate();
const email = watch("email");
const password = watch("password");
const [userLogin, { isLoading, isError, isSuccess, error, data }] =
useUserLoginMutation();
useEffect(() => {
if (isSuccess) {
toast({
title: "Login Successful.",
status: "success",
duration: 9000,
isClosable: true,
});
navigate("/");
window.location.reload();
}
if (isError) {
toast({
title: error?.data?.message,
status: "error",
duration: 5000,
isClosable: true,
});
}
}, [isSuccess, toast, navigate, isError, error?.data]);
const onSubmit = (data) => {
userLogin(data);
};
...
当我第一次登录userInfo
时,我使用useSelector
获得的数据是空的,一旦刷新,就会用localStorage数据填充。
我假设redux store存储/检索信息的方式是异步的,但我对应该采用哪种方法感到困惑。还有,当有一个api调用更新用户信息时该怎么办?我也应该在每次发生这种情况时刷新吗?
1条答案
按热度按时间f8rj6qna1#
你似乎对几个关键概念有点误解:
现在忽略状态持久性,reducer函数应该只使用您希望状态具有的值来更新状态。当状态更新时,这将触发订阅的( 到该状态 )组件重新呈现并接收当前***
userInfo
状态值。示例:
在紧要关头,你当然可以从reducer函数中更新localStorage,但这会被许多人认为是反模式的,应该尽可能避免。
最好是从一个动作中发出副作用,例如:在API切片的查询/变化的
onQueryStarted
属性中,或者简单地集成一个redux状态持久化解决方案/库,如redux-persist
(* 另请参阅持久化和再水合 *)。