Redux-toolkit: Use createAction with createSlice

Created on 4 Feb 2020  路  4Comments  路  Source: reduxjs/redux-toolkit

I want to use a combination of createAction and createSlice.

The success reducer is triggered but the fetch reducer is not triggered.

const FETCH_FORECAST_WEATHER = `${actionName}/fetch`;
const fetch = createAction<string>(FETCH_FORECAST_WEATHER);

const reducers = {
  [FETCH_FORECAST_WEATHER]: (state: ForecastWeatherState) => {
    state.fetchState = FetchStatusCode.LOADING;
  },
 success: (state: ForecastWeatherState, { payload }: PayloadAction<ForecastWeatherState>) => {
    console.log('success1', payload);
    state.list = payload.list;
    state.fetchState = FetchStatusCode.OK;
  },
}

const _ = createSlice({ name: actionName, initialState, reducers });

export const forecastWeatherReducer = _.reducer;
export const forecastWeatherActions = {
  ..._.actions,
  fetch,
};

Most helpful comment

@jjalonso also, you can of course use the actions in slice.action in your saga, no need to create these externally just for use in a saga.
If some are saga-only, but still somehow related to a slice, you can just make empty reducers for them.

All 4 comments

There's two issues here.

The first is that the snippet appears to be incomplete. I'm assuming that it's actually part of some kind of larger function? Because otherwise I don't see where actionName is coming from.

Second, createSlice() will auto-generate action creators for every key in the reducers object, by combining the name field with the key value.

So, if we assume actionName in your snippet is, say, "weather", your code is actually generating an action type of "weather/weather/fetch", and the reducer will only run when it sees that generated action type. The one you created by calling createAction() yourself isn't the same, and so dispatching it does nothing.

You _can_ use the extraReducers argument to createSlice for this kind of use case:

createSlice({
    name,
    initialState,
    reducers: {a, b, c},
    extraReducers: {
        [someOtherActionType]: (state, action) => {}
    }
})

That said, I'm curious what the other actions are that need to be mixed in with the slice's behavior.

@markerikson Hi,

Let me take the chance to ask you, I have a similar scenario and my reducer on createSlice doesn't work, I'm using actionCreators and using it on the same way using [actionName] notation under reducers prop.

The reason why I'm using action creator is because Im using saga, some action are in the reducers and some others not, because they are saga-only. thats the reason why i create all with actions creator and use the [] syntax, but doesnt work, are we using it wrongly?

@jjalonso: per the comment I made above, any fields in the reducers object cause new action creators to be generated. If you want to have this slice handle actions that were defined elsewhere, you need to reference those in the extraReducers field, not reducers.

@jjalonso also, you can of course use the actions in slice.action in your saga, no need to create these externally just for use in a saga.
If some are saga-only, but still somehow related to a slice, you can just make empty reducers for them.

Was this page helpful?
0 / 5 - 0 ratings