我想在頁面載入時實作授權使用者的邏輯。最初,我想檢查cookie中是否有令牌(checkUserToken
),如果有或沒有 - 呼叫另一個函數(fetchUserData
),該函數將來會向伺服器發出請求。最後,當伺服器回應時 - 呼叫第三個函數(setUserData
),該函數將使用使用者資料填充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
我如何在我的slice中實現類似的功能?
P粉4594409912023-09-18 00:41:32
Reducer函數是純函數,它們不會執行像分發動作這樣的副作用。 checkUserToken
不能分發任何動作,fetchUserData
不能傳回函數值。在我看來,checkUserToken
和 fetchUserData
其實是非同步動作。為它們建立一個thunk action。
範例:
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;
請注意,fetchUserData
動作可以直接存取 cookies/token,fetchUserData.fulfilled
reducer case 也可以設定/更新使用者資料狀態。這意味著 setUserData
和 checkUserToken
動作可能是不必要的。