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 populateuserData
'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?
Reducer functions are pure functions, they do not perform side effects like dispatching actions.
checkUserTokencannot dispatch any actions,fetchUserDatacannot return function values. It seems to me thatcheckUserTokenandfetchUserDataare actually asynchronous actions. Create athunk actionfor 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
fetchUserDataaction can directly access cookies/tokens, and thefetchUserData.fulfilledreducer case can also set/update user data status. This means that thesetUserDataandcheckUserTokenactions may be unnecessary.