为什么操作无法使用 redux 工具包正确分派?

问题描述 投票:0回答:1

我有这片:

const studentSlice = createSlice({
  name: 'studentSlice',
  initialState: {
    data: {},
    loading: false,
    error: null,
  },
  reducers: {
    setData: (state, action) => {
      state.data = action.payload;
    },
    setLoading: (state, action) => {
      state.loading = action.payload;
    },
    setError: (state, action) => {
      state.error = action.payload;
    },
  },
});
export const { setData, setLoading, setError } = studentSlice.actions;
export default studentSlice.reducer;

我尝试创建一个使用多个减速器的操作:

export const getStudentData =
  (): any => async (dispatch: any) => {
    try {
      console.log("here");
      dispatch(setLoading(true));
      const {
        data,
        isLoading,
        error
      } = await personApi.endpoints.getStudentList.useQueryState(); // Using RTK Query
      console.log(data);

      if (isLoading) {
        return;
      }

      if (error) {
        throw error;
      }

      dispatch(setData(data));
      dispatch(setLoading(false));
    } catch (error) {
      dispatch(setError(error));
    }
  };

在我的组件中,使用

useEffect
,我尝试调度操作

const StudentProfile = () => {
    const dispatch = useDispatch();
    useEffect(() => {
        dispatch(getStudentData())
    }, [])
    
    const students = useSelector((state: any) => state.student.data))

    return ... // some components that use this students
}

但是

getStudentData
操作不会执行(没有打印日志)。为什么会发生这种情况以及如何正确调度操作?


我最近尝试使用 extraReducers here 但切片的状态也没有改变。


这是我的 API 切片代码:

const personApi = api.injectEndpoints({
  endpoints: (builder) => ({
    getStudentList: builder.query<StudentsResult, void>({
      query: () => ({
        url: 'students',
        method: 'POST',
        body: JSON.stringify({
          // some fields
        }),
      }),
      providesTags: ['Students'],
    }),
  }),
});
next.js redux redux-toolkit
1个回答
0
投票

我想将

createApi
中的数据存储到 [
studentSlice
] 切片中。

您可以创建减速器案例来匹配活动查询/变更的待处理、已完成和拒绝状态。

const studentSlice = createSlice({
  name: 'studentSlice',
  initialState: {
    data: {},
    loading: false,
    error: null,
  },
  reducers: {
    ....
  },
  extraReducers: builder => {
    builder
      .addMatcher(
        personApi.endpoints.getStudentList.matchPending,
        (state) => {
          state.loading = true;
        },
      )
      .addMatcher(
        personApi.endpoints.getStudentList.matchFulfilled,
        (state, action) => {
          state.loading = false;
          state.error = null;
          state.data = action.payload;
        },
      )
      .addMatcher(
        personApi.endpoints.getStudentList.matchRejected,
        (state, action) => {
          state.loading = false;
          state.error = action.payload;
        },
      );
  },
});

使用生成的

getStudentList
useGetStudentList
 挂钩启动 
useLazyGetStudentList
查询。

const queryResult = useGetStudentList();
const [getStudents, queryResult] = useLazyGetStudentList();

或者,如果您真的仍然想使用Thunk,则使用

createAsyncThunk
,以便为您生成待处理、已完成和拒绝的操作,并手动启动端点。请注意,由于您仍然需要
extraReducers
,因此与上面使用查询匹配器的首选方法相比,没有净收益。

示例:

import { createAsyncThunk } from '@reduxjs/toolkit';

export const getStudentData = createAsyncThunk(
  "students/getStudentData",
  async (_, thunkApi) => {
    try {
      const { data, error } = await thunkApi.dispatch(
        personApi.endpoints.getStudentList.initiate()
      );

      if (error) {
        throw error;
      }

      return data;
    } catch (error) {
      return thunkApi.rejectWithValue(error);
    }
  }
);
const studentSlice = createSlice({
  name: 'studentSlice',
  initialState: {
    data: {},
    loading: false,
    error: null,
  },
  reducers: {
    ....
  },
  extraReducers: builder => {
    builder
      .addCase(getStudentData.pending, (state) => {
        state.loading = true;
      })
      .addCase(getStudentData.fulfilled, (state, action) => {
        state.loading = false;
        state.error = null;
        state.data = action.payload;
      })
      .addCase(getStudentData.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  },
});
© www.soinside.com 2019 - 2024. All rights reserved.