profile
viewpoint

Ask questionsDefault reducer for slice

Currently it seems there's no way to add a default reducer to a slice. This is useful when using libraries like normalizr with an entities slice. The entities slice listens for all actions and then checks for the presence of entities in the payload.

Currently I had to create an old fashioned reducer for using normalizr. It would be useful if createSlice offers a defaultReducer or something like that that runs for all actions.

This is what I'm currently using

import merge from 'lodash/merge'
import produce from 'immer'

const entitiesSliceName = 'entities'

function entitiesReducer(baseState = {}, { payload }) {
  if (!payload || !payload.entities) return baseState

  return produce(baseState, draftState => {
    merge(draftState, payload.entities)
  })
}

export default {
  reducer: entitiesReducer,
  name: entitiesSliceName,
}

This is what I think could be usefull

import { createSlice } from '@reduxjs/toolkit'
import merge from 'lodash/merge'

const entitiesSlice = createSlice({
  name: 'entities',
  initialState: 0,
  defaultReducer: (state, { payload = {} }) => merge(state, payload.entities),
})

export default entitiesSlice
reduxjs/redux-toolkit

Answer questions arnotes

ok my apologies. I just mean it would be nice to have an internal utility similar to this

type childSelector<P,C> = (state:P) => C;
export const forwardReducer = <P,C>(childSlice:Slice<C>,childSelector:childSelector<P,C>) => {
    const reducerDC = {} as any;//will fix types later
    for (const key in childSlice.actions) {
        if (childSlice.actions.hasOwnProperty(key)) {
            const action = childSlice.actions[key];
            reducerDC[action.type] = (state:P, action:any) => {
                childSlice.reducer(childSelector(state), action);
            }
        }
    }
    console.log({reducerDC, childSlice});
    return reducerDC;
}

and use it like this

export const teacherSlice = createSlice({
    name: 'teacher',
    initialState: {student:{}} as any as teacher,
    reducers:{
        setName:(state, action) => {
            state.teacherName = action.payload
        }
    },
    extraReducers: forwardReducer<teacher, student>(studentSlice, state => state.student)
})
useful!

Related questions

No questions were found.
source:https://uonfu.com/
Github User Rank List