uso react medium instalar español javascript redux

javascript - react - ¿Acceso al estado de Redux en un creador de acción?



redux saga español (5)

Cuando su escenario es simple, puede usar

import store from ''../store''; export const SOME_ACTION = ''SOME_ACTION''; export function someAction() { return { type: SOME_ACTION, items: store.getState().otherReducer.items, } }

Pero a veces su action creator necesita activar acciones múltiples

por ejemplo, solicitud asíncrona, por lo que necesita las acciones REQUEST_LOAD REQUEST_LOAD_SUCCESS REQUEST_LOAD_FAIL

export const [REQUEST_LOAD, REQUEST_LOAD_SUCCESS, REQUEST_LOAD_FAIL] = [`REQUEST_LOAD` `REQUEST_LOAD_SUCCESS` `REQUEST_LOAD_FAIL` ] export function someAction() { return (dispatch, getState) => { const { items } = getState().otherReducer; dispatch({ type: REQUEST_LOAD, loading: true }); $.ajax(''url'', { success: (data) => { dispatch({ type: REQUEST_LOAD_SUCCESS, loading: false, data: data }); }, error: (error) => { dispatch({ type: REQUEST_LOAD_FAIL, loading: false, error: error }); } }) } }

Nota: necesita redux-thunk para devolver la función en el creador de la acción

Digamos que tengo lo siguiente:

export const SOME_ACTION = ''SOME_ACTION''; export function someAction() { return { type: SOME_ACTION, } }

Y en ese creador de acciones, quiero acceder al estado de la tienda global (todos los reductores). ¿Es mejor hacer esto?

import store from ''../store''; export const SOME_ACTION = ''SOME_ACTION''; export function someAction() { return { type: SOME_ACTION, items: store.getState().otherReducer.items, } }

o esto:

export const SOME_ACTION = ''SOME_ACTION''; export function someAction() { return (dispatch, getState) => { const {items} = getState().otherReducer; dispatch(anotherAction(items)); } }


Estoy de acuerdo con @Bloomca. Pasar el valor necesario de la tienda a la función de despacho como argumento parece más simple que exportar la tienda. Hice un ejemplo aquí:

import React from "react"; import {connect} from "react-redux"; import * as actions from ''../actions''; class App extends React.Component { handleClick(){ const data = this.props.someStateObject.data; this.props.someDispatchFunction(data); } render(){ return ( <div> <div onClick={ this.handleClick.bind(this)}>Click Me!</div> </div> ); } } const mapStateToProps = (state) => { return { someStateObject: state.someStateObject }; }; const mapDispatchToProps = (dispatch) => { return { someDispatchFunction:(data) => { dispatch(actions.someDispatchFunction(data))}, }; } export default connect(mapStateToProps, mapDispatchToProps)(App);


Hay diferentes opiniones sobre si acceder a los creadores de estado en acción es una buena idea. Los pocos casos de uso en los que creo que es aceptable es para verificar los datos almacenados en caché antes de realizar una solicitud, o para verificar si está autenticado (en otras palabras, hacer un envío condicional). Creo que pasar datos como state.something.items en un creador de acciones es definitivamente un antipatrón y se desaconseja porque oscurece el historial de cambios: si hay un error y los items son incorrectos, es difícil rastrear dónde están esos incorrectos los valores provienen porque ya son parte de la acción, en lugar de ser calculados directamente por un reductor en respuesta a una acción. Hazlo con cuidado. (Para obtener más información sobre los pros y los contras de acceder a los creadores del estado en acción, vea la publicación del blog Idiomatic Redux: Reflexiones sobre Thunks, Sagas, Abstracción y Reutilización ).

Si encuentra que necesita esto, ambos enfoques que sugirió están bien. El primer enfoque no requiere ningún middleware:

import store from ''../store''; export const SOME_ACTION = ''SOME_ACTION''; export function someAction() { return { type: SOME_ACTION, items: store.getState().otherReducer.items, } }

Sin embargo, puede ver que depende de que la store sea ​​un singleton exportado desde algún módulo. No lo recomendamos porque hace que sea mucho más difícil agregar la representación del servidor a su aplicación porque en la mayoría de los casos en el servidor querrá tener una tienda separada por solicitud . Entonces, aunque técnicamente este enfoque funciona, no recomendamos exportar una tienda desde un módulo.

Por eso recomendamos el segundo enfoque:

export const SOME_ACTION = ''SOME_ACTION''; export function someAction() { return (dispatch, getState) => { const {items} = getState().otherReducer; dispatch(anotherAction(items)); } }

Te requeriría usar el middleware Redux Thunk, pero funciona bien tanto en el cliente como en el servidor. Puede leer más sobre Redux Thunk y por qué es necesario en este caso here .

Idealmente, sus acciones no deben ser "gordas" y deben contener la menor información posible, pero debe sentirse libre de hacer lo que mejor le funcione en su propia aplicación. Las preguntas frecuentes de Redux tienen información sobre la división de la lógica entre los creadores y reductores de acciones y los momentos en que puede ser útil usar getState en un creador de acciones .


Me gustaría señalar que no es tan malo leer de la tienda; podría ser mucho más conveniente decidir qué hacer en función de la tienda, que pasar todo al componente y luego como un parámetro de Una función. Estoy completamente de acuerdo con Dan en que es mucho mejor no utilizar store como singleteone, a menos que esté 100% seguro de que solo lo usará para la representación del lado del cliente (de lo contrario, podrían aparecer errores difíciles de rastrear).

Creé una biblioteca recientemente para tratar la verbosidad de redux, y creo que es una buena idea poner todo en el middleware, para que tenga todo como inyección de dependencia.

Entonces, su ejemplo se verá así:

import { createSyncTile } from ''redux-tiles''; const someTile = createSyncTile({ type: [''some'', ''tile''], fn: ({ params, selectors, getState }) => { return { data: params.data, items: selectors.another.tile(getState()) }; }, });

Sin embargo, como puede ver, realmente no modificamos los datos aquí, por lo que hay una buena posibilidad de que podamos usar este selector en otro lugar para combinarlo en otro lugar.


Presentando una forma alternativa de resolver esto. Esto puede ser mejor o peor que la solución de Dan, dependiendo de su aplicación.

Puede obtener el estado de los reductores en las acciones dividiendo la acción en 2 funciones separadas: primero solicite los datos, segundo acto sobre los datos. Puede hacerlo utilizando redux-loop .

Primero ''solicite amablemente los datos''

export const SOME_ACTION = ''SOME_ACTION''; export function someAction() { return { type: SOME_ACTION, } }

En el reductor, intercepte la solicitud y proporcione los datos a la acción de la segunda etapa utilizando redux-loop .

import { loop, Cmd } from ''redux-loop''; const initialState = { data: '''' } export default (state=initialState, action) => { switch(action.type) { case SOME_ACTION: { return loop(state, Cmd.action(anotherAction(state.data)) } } }

Con los datos en la mano, haga lo que quiera inicialmente

export const ANOTHER_ACTION = ''ANOTHER_ACTION''; export function anotherAction(data) { return { type: ANOTHER_ACTION, payload: data, } }

Espero que esto ayude a alguien.