Redux-toolkit - extraReducer 中出现类型错误的原因可能是什么?

Redux-toolkit - What could be the reason for a type-error in an extraReducer?

我的 redux-slice 出现以下错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'type')
    at Object.addCase (mapBuilders.ts:158:1)
    at extraReducers (boerseSlice.js:89:1)
    at executeReducerBuilderCallback (mapBuilders.ts:194:1)
    at buildReducer (createSlice.ts:300:1)
    at reducer (createSlice.ts:323:1)
    at redux.js:436:1
    at Array.forEach (<anonymous>)
    at assertReducerShape (redux.js:434:1)
    at combineReducers (redux.js:499:1)
    at configureStore (configureStore.ts:144:1)

这是我切片的第 89 行:

.addCase(createBoersenwerte.fulfilled, (state,action)=>{
            state.isLoading = false;
            state.isSuccess = true;
            state.boersenwerte.push(action.payload);
        })

这是完整的切片:

import {createSlice, createAsyncThunk} from "@reduxjs/toolkit"
import boersenwerteService from "./boersenwerteService";
const initialState = {
    boersenwerte: [],
    isLoading:false,
    isError:false,
    isSuccess:false,
    message:"",
}
export const createBoersenwerte = createAsyncThunk("boersenwerte/", async (boersenwerteData, thunkAPI)=>{
    try{
        const token = thunkAPI.getState().auth.user.token;
        return await boersenwerteService.createBoersenwerte(boersenwerteData, token);
    } catch(error){
        const message = (error.response && 
            error.response.data && 
            error.response.data.message)
            || error.message
            || error.toString()
            return thunkAPI.rejectWithValue(message);
    }
})
//update
export const updateBoersenwerte = createAsyncThunk("/boersenwerte/update", async (id, thunkAPI)=>{
    try{
        const token = thunkAPI.getState().auth.user.token;
        return await boersenwerteService.updateBoersenwerte(id, token);
    } catch(error){
        const message = (error.response 
            && error.response.data 
            && error.response.data.message) 
            || error.message 
            || error.toString();
        return thunkAPI.rejectWithValue(message);
    }
})
//delete
export const deleteBoersenwerte = createAsyncThunk("/boersenwerte/delete", async (id, thunkAPI)=>{
    try{
        const token = thunkAPI.getState().auth.user.token;
        return await boersenwerteService.deleteBoersenwerte(id, token);
    } catch(error){
        const message = (error.response 
            && error.response.data 
            && error.response.data.message) 
            || error.message 
            || error.toString();
        return thunkAPI.rejectWithValue(message);
    }
})
//getOne
export const getBoersenwerte = createAsyncThunk("/boersenwerte/find/", async (id, thunkAPI)=>{
    try{
        return await boersenwerteService.getBoersenwerte(id);
    } catch(error){
        const message = (error.response 
            && error.response.data 
            && error.response.data.message) 
            || error.message 
            || error.toString();
        return thunkAPI.rejectWithValue(message);
    }
})
//getall
export const getAllBoersenwerte = createAsyncThunk("/boersenwerte/find", async (_, thunkAPI)=>{
    try{
        return await boersenwerteService.getAllBoersenwerte();
    } catch(error){
        const message = (error.response 
            && error.response.data 
            && error.response.data.message) 
            || error.message 
            || error.toString();
        return thunkAPI.rejectWithValue(message);
    }
})


export const boersenwerteSlice = createSlice({
    name:"boersenwerte",
    initialState,
    reducers:{
        reset: (state)=>initialState,
    }, extraReducers: (builder)=>{
        builder
        .addCase(createBoersenwerte.pending, (state)=>{
            state.isLoading = true;
        })
        .addCase(createBoersenwerte.fulfilled, (state,action)=>{
            state.isLoading = false;
            state.isSuccess = true;
            state.boersenwerte.push(action.payload);
        })
        .addCase(createBoersenwerte.rejected, (state,action)=>{
            state.isLoading = false;
            state.isError = true;
            state.message = action.payload;
        })
        .addCase(updateBoersenwerte.pending, (state)=>{
            state.isLoading = true;
        })
        .addCase(updateBoersenwerte.fulfilled, (state, action)=>{
            state.isLoading = false;
            state.isSuccess = true;
            state.boersenwerte.push(action.payload);
        })
        .addCase(updateBoersenwerte.rejected, (state, action)=>{
            state.isLoading = false;
            state.isError = true;
            state.message = action.payload;
        })
        .addCase(deleteBoersenwerte.pending, (state)=>{
            state.isLoading = true;
        })
        .addCase(deleteBoersenwerte.fulfilled, (state, action)=>{
            state.isLoading = false;
            state.isSuccess = true;
            state.boersenwerte = state.boersenwerte.filter((boersenwerte)=> boersenwerte._id !== action.payload.id);
        })
        .addCase(deleteBoersenwerte.rejected, (state, action)=>{
            state.isLoading = false;
            state.isError = true;
            state.message = action.payload;
        })
        .addCase(getBoersenwerte.pending, (state)=>{
            state.isLoading = true;
        })
        .addCase(getBoersenwerte.fulfilled, (state, action)=>{
            state.isLoading = false;
            state.isSuccess = true;
            state.boersenwerte = action.payload;
        })
        .addCase(getBoersenwerte.rejected, (state, action)=>{
            state.isLoading = false;
            state.isError = true;
            state.message = action.payload;
        })
        .addCase(getAllBoersenwerte.pending, (state)=>{
            state.isLoading = true;
        })
        .addCase(getAllBoersenwerte.fulfilled, (state, action)=>{
            state.isLoading = false;
            state.isSuccess = true;
            state.boersenwerte = action.payload;
        })
        .addCase(getAllBoersenwerte.rejected, (state, action)=>{
            state.isLoading = false;
            state.isError = true;
            state.message = action.payload;
        })
    }
})
export const {reset} = boersenwerteSlice.actions;
export default boersenwerteSlice.reducer;

这是完整的服务文件:

import axios from "axios";

const API_URL = "/api/boersenwerte/";

const createBoersenwerte = async (boersenwerteData, token)=>{
    const config ={
        headers:{
        accessToken: token,
        }
    }
    const response = await axios.post(API_URL, boersenwerteData, config);
    return response.data;
}
//update
const updateBoersenwerte = async (boersenwerteId,  boersenwerteData, token)=>{
    const config = {
          headers:{
        accessToken: token,
        }
    }
    const response = await axios.put(API_URL + boersenwerteId,  boersenwerteData, config);
    return response.data;
}
//delete
const deleteBoersenwerte = async (boersenwerteId, token)=>{
    const config = {
          headers:{
        accessToken: token,
        }
    }
    const response = await axios.delete(API_URL + boersenwerteId, config);
    return response.data;
}
//getOne
const getBoersenwerte = async (boersenwerteId)=>{
   
    const response = await axios.get(API_URL + boersenwerteId);
    return response.data;
}
//getAll
const getAllBoersenwerte = async ()=>{
   
    const response = await axios.get(API_URL);
    return response.data;
}

const boersenwerteService = {
    createBoersenwerte,
    updateBoersenwerte,
    deleteBoersenwerte,
    getBoersenwerte,
    getAllBoersenwerte,
}
export default boersenwerteService;

感谢您的帮助。

问题是您没有提供 createBoersenwerte thunk 的动作名称,请尝试更改此名称:

// add create after the slash
export const createBoersenwerte = createAsyncThunk("boersenwerte/create", async (boersenwerteData, thunkAPI)=>{
    try{
        const token = thunkAPI.getState().auth.user.token;
        return await boersenwerteService.createBoersenwerte(boersenwerteData, token);
    } catch(error){
        const message = (error.response && 
            error.response.data && 
            error.response.data.message)
            || error.message
            || error.toString()
            return thunkAPI.rejectWithValue(message);
    }
})

查看您的代码,我注意到您对两个 thunk 使用相同的操作名称,您必须更改它以避免进一步的错误:

// changed to findAll
export const getAllBoersenwerte = createAsyncThunk("/boersenwerte/findAll", async (_, thunkAPI)=>{
    try{
        return await boersenwerteService.getAllBoersenwerte();
    } catch(error){
        const message = (error.response 
            && error.response.data 
            && error.response.data.message) 
            || error.message 
            || error.toString();
        return thunkAPI.rejectWithValue(message);
    }
})

最后一件事,也许它不适合你的情况,但了解一些技巧总是好的,redux-toolkit 为 [=13] 提供了 匹配实用程序 =],您可以使用它来减少为多个 thunk 定义相同逻辑的 reducer 的重复,take a look here