在行動中採取行動:利用嵌套行動在下一個Redux中發揮作用
P粉614840363
P粉614840363 2023-09-17 08:40:23
0
1
493

我想在頁面載入時實作授權使用者的邏輯。最初,我想檢查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粉614840363
P粉614840363

全部回覆(1)
P粉459440991

Reducer函數是純函數,它們不會執行像分發動作這樣的副作用。 checkUserToken 不能分發任何動作,fetchUserData 不能傳回函數值。在我看來,checkUserTokenfetchUserData 其實是非同步動作。為它們建立一個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 也可以設定/更新使用者資料狀態。這意味著 setUserDatacheckUserToken 動作可能是不必要的。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板