examples javascript redux reducers

javascript - examples - Redux: Colectores selectores con reductores



jquery selector examples (1)

En este tutorial de Redux: Colocating Selectors with Reducers Egghead, Dan Abramov sugiere usar selectores que acepten el árbol de estado completo , en lugar de segmentos de estado, para encapsular el conocimiento del estado lejos de los componentes. Argumenta que esto hace que sea más fácil cambiar la estructura del estado ya que los componentes no tienen conocimiento de ella, con lo que estoy completamente de acuerdo.

Sin embargo, el enfoque que sugiere es que para cada selector correspondiente a una porción particular de estado, lo definimos nuevamente junto con el reductor de raíz para que pueda aceptar el estado completo. Seguramente, esta sobrecarga de implementación socava lo que está tratando de lograr ... simplificando el proceso de cambiar la estructura del estado en el futuro.

En una aplicación grande con muchos reductores, cada uno con muchos selectores, ¿no nos encontraremos inevitablemente con colisiones de nombres si estamos definiendo todos nuestros selectores en el archivo del reductor raíz? ¿Qué tiene de malo importar un selector directamente desde su reductor relacionado y pasar el estado global en lugar del estado correspondiente? p.ej

const todos = (state = [], action) => { switch (action.type) { case ''ADD_TODO'': return [...state, todo(undefined, action)]; case ''TOGGLE_TODO'': return state.map(t => todo(t, action)); default: return state; } }; export default todos; export const getVisibleTodos = (globalState, filter) => { switch (filter) { case ''all'': return globalState.todos; case ''completed'': return globalState.todos.filter(t => t.completed); case ''active'': return globalState.todos.filter(t => !t.completed); default: throw new Error(`Unknown filter: ${filter}.`); } };

¿Hay alguna desventaja de hacerlo de esta manera?


Después de haber cometido este error (no con Redux, pero con un marco de flujo interno similar), el problema es que su enfoque sugerido acopla los selectores a la ubicación del estado del reductor asociado en el árbol de estado general. Esto causa un problema en algunos casos:

  • Desea tener el reductor en varias ubicaciones en el árbol de estado (por ejemplo, porque el componente relacionado aparece en varias partes de la pantalla o es usado por varias pantallas independientes de su aplicación).
  • Desea reutilizar el reductor en otra aplicación, y la estructura de estado de esta aplicación es diferente de su aplicación original.

También agrega una dependencia implícita de su reductor de raíz a los selectores de cada módulo (ya que tienen que saber en qué clave están, lo que realmente es responsabilidad del reductor de raíz).

Si un selector necesita un estado de varios reductores diferentes, el problema se puede ampliar. Idealmente, el módulo debería simplemente exportar una función pura que transforme la porción de estado al valor requerido, y depende de los archivos del módulo raíz de la aplicación para conectarlo.

Un buen truco es tener un archivo que solo exporte selectores, todos tomando la porción de estado. De esa manera se pueden manejar en un lote:

// in file rootselectors.js import * as todoSelectors from ''todos/selectors''; //... // something like this: export const todo = shiftSelectors(state => state.todos, todoSelectors);

(shiftSelectors tiene una implementación simple: sospecho que la biblioteca reseleccionar ya tiene una función adecuada).

Esto también le da espacio entre los nombres, todos los selectores de tareas están disponibles bajo la exportación ''todo''. Ahora, si tiene dos listas de tareas pendientes, puede exportar fácilmente tareas1 y todo2, e incluso proporcionar acceso a las dinámicas exportando una función memorizada para crearlas para un índice o identificación en particular, por ejemplo. (por ejemplo, si puede mostrar un conjunto arbitrario de listas de tareas a la vez). P.ej

export const todo = memoize(id => shiftSelectors(state => state.todos[id], todoSelectors)); // but be careful if there are lot of ids!

A veces los selectores necesitan un estado de varias partes de la aplicación. Nuevamente, evite cablear excepto en la raíz. En tu módulo, tendrás:

export function selectSomeState(todos, user) {...}

y luego su archivo de selectores raíz puede importar eso, y volver a exportar la versión que conecta ''todos'' y ''usuario'' a las partes apropiadas del árbol de estado.

Por lo tanto, para una aplicación pequeña y desechable, probablemente no sea muy útil y solo agrega repetitivo (especialmente en JavaScript, que no es el lenguaje funcional más conciso). Para un conjunto de aplicaciones de gran tamaño que utiliza muchos componentes compartidos, va a permitir una gran reutilización y mantiene las responsabilidades claras. También hace que los selectores de nivel de módulo sean más simples, ya que no tienen que bajar primero al nivel apropiado. Además, si agrega FlowType o TypeScript, evita el problema realmente grave de que todos sus submódulos tengan que depender de su tipo de estado raíz (básicamente, la dependencia implícita que mencioné se hace explícita).