Estructura de archivos Ducks para Redux.js

Al realizar una aplicación con Redux es muy común manejar la siguiente estructura de archivos:

|_ /actions   # Los creadores de acciones
|_ /constants # Las constantes, como los tipos de acciones
|_ /reducers # Los reducers de la aplicación

Aunque esta forma funciona, con el tiempo uno se encuentra casos donde un reducer tiene un solo tipo de acción posible y por lo tanto un solo creador de acciones. Y sin embargo terminamos creando al menos tres archivos para eso (aunque los tipos de acciones se pueden guardar todos juntos).

Para solucionar eso existe Ducks.

Que es

Ducks es una forma de modularizar partes de una aplicación de Redux juntando reducers, tipos de acciones y creadores de acciones juntos de una forma fácil de entender y portar.

El nombre del formato (ducks) viene de la pronunciación de la última sílaba de Redux en inglés.

Como funciona

Veamos un ejemplo simple en código primero.

// tipo de acción
const CHANGE_FILTER = 'my-app/filters/CHANGE_FILTER';
// nuestro reducer
export default function reducer(state = '', action = {}) {
switch (action.type) {
case CHANGE_FILTER:
return action.payload;
default:
return state;
}
}
// creador de acciones
export function changeFilter(filter) {
return { type: CHANGE_FILTER, payload: filter };
}

Un módulo de Ducks debe seguir ciertas reglas (que se ven reflejadas en el código anterior).

Reglas

Un módulo…

  1. DEBE exportar por defecto una función llamada reducer().
  2. DEBE exportar sus creadores de acciones como funciones.
  3. DEBE definir sus tipos de acciones en el formato modulo-app/reducer/ACTION_TYPE.
  4. PUEDE exportar sus tipos de acciones como UPPER_SNAKE_CASE si otro reducer la va a usar o si esta publicada como una librería reusable.

Como usarlo

Para usarlo simplemente importas el duck en tu listado de reducers de la siguiente forma.

import { combineReducers } from 'redux';
// los reducers
import filters from './ducks/filters';
export default combineReducers({
filters,
});

También es posible importar los creadores de acciones.

import * as filtersActions from './ducks/filters';
// o
import { changeFilter } from './ducks/filters';

Y así vas a importarlos listos para ser usados

Conclusión

Implementar e incluso migrar a esta estructura es muy fácil y ayuda mucho a mejorar nuestra experiencia como desarrolladores al hacer nuestros proyectos son más mantenibles a largo plazo y fácil de entender para nuevos desarrolladores.