es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Existe una forma mejor de dividir los reducers en fragmentos más pequeños?

Quiero tener un objeto en la tienda con objetos más pequeños adentro, como se muestra en el ejemplo. Pero tengo un gran número de reductores que quiero dividir en piezas más pequeñas.
Actualmente estoy pensando en la siguiente solución.

// Almacenamiento Redux final que quiero tener
largeObj: {
  someValue: 'Algún valor',
  smallObjA: {...},
  smallObjB: {...}
}
// myReducer.js
import { initialState: initialStateA, reducersA } from './reducersA.js';
import { initialState: initialStateB, reducersB } from './reducersB.js';

const initialState = {
  someVal: '',
  smallObjA: initialStateA,
  smallObjB: initialStateB
}

export const mySlice = createSlice({
  name: 'myState',
  reducers: {
    updateSomeVal: (state, action) => state.someVal = action.payload,
    ...reducersA,
    ...reducersB
  }
});
// reducersA.js
export const initialState = {...};

export const reducersA = {
  reducer1: (state, action) => {...},
  reducer2: (state, action) => {...},
  .....
  reducerN: (state, action) => {...},
};
// reducersB.js
export const initialState = {...};

export const reducersB = {
  reducer1: (state, action) => {...},
  reducer2: (state, action) => {...},
  .....
  reducerN: (state, action) => {...},
};

¿Puede sugerir una mejor solución para resolver eso?

PD: no estoy seguro de cómo se puede resolver con combineReducers debido a “someVal” que debería estar en el objeto principal.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible solución para dividir aún más los reducers manteniendo la estructura deseada de la tienda de Redux es utilizar slices anidados con Redux Toolkit. Los slices anidados permiten que los reducers operen en una parte de la tienda mientras aún pueden acceder al estado padre. Aquí tienes un ejemplo:

    // parentSlice.js
    import { createSlice } from '@reduxjs/toolkit';
    import { childASlice } from './childASlice';
    import { childBSlice } from './childBSlice';
    
    const initialState = {
      someVal: '',
      smallObjA: childASlice.initialState,
      smallObjB: childBSlice.initialState
    };
    
    export const parentSlice = createSlice({
      name: 'parent',
      initialState,
      reducers: {
        updateSomeVal: (state, action) => {
          state.someVal = action.payload;
        }
      },
      extraReducers: (builder) => {
        builder.addCase(childASlice.actions.someChildAAction, (state, action) => {
          // acceder al estado padre
          console.log(state.someVal);
          // actualizar el estado del hijo
          state.smallObjA = childASlice.reducer(state.smallObjA, action);
        });
        builder.addCase(childBSlice.actions.someChildBAction, (state, action) => {
          // acceder al estado padre
          console.log(state.someVal);
          // actualizar el estado del hijo
          state.smallObjB = childBSlice.reducer(state.smallObjB, action);
        });
      },
    });
    
    // childASlice.js
    import { createSlice } from '@reduxjs/toolkit';
    
    export const childASlice = createSlice({
      name: 'childA',
      initialState: {...},
      reducers: {...},
    });
    
    // childBSlice.js
    import { createSlice } from '@reduxjs/toolkit';
    
    export const childBSlice = createSlice({
      name: 'childB',
      initialState: {...},
      reducers: {...},
    });
    

    En este ejemplo, parentSlice es el slice padre que contiene el objeto principal en la tienda con objetos más pequeños dentro. childASlice y childBSlice son dos slices hijos que operan en smallObjA y smallObjB respectivamente. El campo extraReducers en parentSlice se utiliza para aplicar acciones que afectan a los slices hijos.

    Con este enfoque, no es necesario combinar reducers con combineReducers ya que Redux Toolkit se encarga de ello automáticamente.

Comments are closed.