搜尋

首頁  >  問答  >  主體

在行動中採取行動:利用嵌套行動在下一個Redux中發揮作用

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

全部回覆(1)我來回復

  • P粉459440991

    P粉4594409912023-09-18 00:41:32

    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 動作可能是不必要的。

    回覆
    0
  • 取消回覆