I want to implement the logic of authorizing users when the page loads. Initially, I wanted to check if there is a token in the cookie (checkUserToken
) and if there is or not - call another function (fetchUserData
) which will make a future request to the server. Finally, when the server responds - the third function (setUserData
) is called which will populate userData
'use client' import { createSlice } from "@reduxjs/toolkit"; import { getCookie } from '@/app/untils/Cookies'; const initialState = { userData: null } export const userSlice = createSlice({ name: "userData", initialState, reducers: { checkUserToken: () => { console.log('chekc') const token = getCookie('user-token'); console.log(token) if (token) return fetchUserData(token) else return fetchUserData(false) }, fetchUserData: async (state, action) => dispatch => { return console.log('FETCH') // console.log(state) // console.log(action) }, setUserData: (state, action) => { console.log('SET USER') console.log(action) console.log(state) } } }) export const { checkUserToken, fetchUserData, setUserData } = userSlice.actions export default userSlice.reducer
How can I implement similar functionality in my slice?
P粉4594409912023-09-18 00:41:32
Reducer functions are pure functions, they do not perform side effects like dispatching actions. checkUserToken
cannot dispatch any actions, fetchUserData
cannot return function values. It seems to me that checkUserToken
and fetchUserData
are actually asynchronous actions. Create a thunk action for them.
Example:
import { createSlice, createAsyncAction } from "@reduxjs/toolkit"; import { getCookie } from '@/app/untils/Cookies'; export const checkUserToken = createAsyncAction( "userData/checkUserToken", (_, thunkAPI) => { console.log('check'); const token = getCookie('user-token'); console.log(token); return thunkAPI.dispatch(fetchUserData(token ?? false)); }, ); export const fetchUserData = createAsyncAction( "userData/fetchUserData", async (token, thunkAPI) => { try { console.log('FETCH'); ... 异步获取逻辑 ... return /* 一些数据??? */ } catch(error) { return thunkAPI.rejectWithValue(error)); } }, ); const initialState = { userData: null, }; export const userSlice = createSlice({ name: "userData", initialState, reducers: { setUserData: (state, action) => { console.log('SET USER'); .... } }, extraReducers: builder => { builder .addCase(fetchUserData.fulfilled, (state, action) => { // 使用返回的 action.payload 值更新用户数据 }) .addCase(fetchUserData.rejected, (state, action) => { // 如有必要,设置任何错误状态 }); }, }) export const { setUserData } = userSlice.actions; export default userSlice.reducer;
Please note that the fetchUserData
action can directly access cookies/tokens, and the fetchUserData.fulfilled
reducer case can also set/update user data status. This means that the setUserData
and checkUserToken
actions may be unnecessary.