redux 如何使一个切片调用reducer对应于另一个分派

4nkexdtk  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(60)

我使用的是React,我有一个Redux-Toolkit(RTK)状态切片,它是用localStorage持久化的(我使用的是redux-persist库)。简单来说就是这样:

const initLocations = []

const locationsPersistentSlice = createSlice({
  {
  name: "locations",
  initLocations,
  reducers: {
    addLocation(prevState, action) {
      // adding new location to store
    },
    clearLocations() {
      return []
    }
  }
})

它能同步工作而且非常好。
但是,我想添加第二个切片locationInfoSlice,它应该在addLocation()操作被调度时使用列表中的最后一个位置获取数据。
我怎么才能做到这一点?我考虑过extraReducersasyncThunk,但没有得到正确的。

krugob8w

krugob8w1#

但是,我想添加第二个切片locationInfoSlice,它应该在addLocation()操作被调度时获取数据,使用列表中的最后一个位置。
如果我正确理解了你的帖子/问题,你实际上想派遣 * 一些 * 单一的行动,并做以下事情:

  • state.locations数组中存储位置
  • 处理一些异步操作/逻辑,以使用state.locations数组中的最后一个位置获取一些数据。

我怎么才能做到这一点?我考虑过extraReducersasyncThunk,但没有得到正确的。
您可能需要使用两者。单独使用extraReducers是不行的,因为reducer函数是没有副作用的纯同步函数,例如:它们不能异步获取数据。我的建议是创建一个Thunk,它调度addLocation操作来更新state.locations的状态,并且还进行所需的数据获取,该数据获取可以返回一个值,该值将用于更新extraReducerslocationInfoSlice的状态。

import { createAsyncThunk } from '@reduxjs/toolkit';
import { addLocation } from '../locationsPersistentSlice';

export const addLocationAsync = createAsyncThunk(
  "locations/addLocationAsync",
  async (location, thunkApi) => {
    // dispatch to add new location
    thunkApi.dispatch(addLocation(location));

    try {
      // asynchronous fetch logic
      return data;
    } catch(error) {
      return thunkApi.rejectWithError(error);
    }
  },
);
import { createSlice } from '@reduxjs/toolkit';

const initialState = [];

const locationsPersistentSlice = createSlice({
  name: "locations",
  initialState,
  reducers: {
    addLocation(state, action) {
      state.push(action.payload);
    },
    clearLocations() {
      return initialState;
    },
  },
});

export const {
  addLocation,
  clearLocations,
} = locationsPersistentSlice.actions;

export default locationsPersistentSlice.reducer;
import { createSlice } from '@reduxjs/toolkit';
import { addLocationAsync } from './action';

const initialState = /* whatever this initial state value is */;

const locationInfoSlice = createSlice({
  name: "locationInfo",
  initialState,
  extraReducers: builder => {
    builder
      .addCase(addLocationAsync.fulfilled, (state, action) => {
        // update state with fetched data
      })
      .addCase(addLocationAsync.rejected, (state, action) => {
        // update state with error status???
      })
      .addCase(addLocationAsync.pending, (state, action) => {
        // set any pending/loading state
      });
  },
});

export default locationInfoSlice.reducer;

在UI中,它现在将调度addLocationAsync操作,而不是直接调度addLocation操作。

import { useDispatch } from 'react-redux';
import { addLocationAsync } from './action';

...

const dispatch = useDispatch();

...

dispatch(addLocationAsync(/* some location value */));

...

相关问题