react example redux

example - ¿Redux tiene una forma integrada de deshacer acciones?



redux thunk (4)

Estoy construyendo una aplicación donde las acciones se realizan a medida que el usuario se desplaza hacia abajo. Sería bueno si pudiera deshacer esas acciones a medida que el usuario se desplaza de nuevo, básicamente convirtiendo el desplazamiento en una forma de navegar a través de la línea de tiempo de las acciones.

¿Hay una forma incorporada en Redux para hacer esto? ¿O tendría que escribir middleware para esto?


No hay una forma incorporada de hacer esto. pero puede inspirarse en cómo funciona redux-dev-tools ( https://github.com/gaearon/redux-devtools ). Básicamente tiene funcionalidad de "viaje en el tiempo" y funciona manteniendo un registro de todas las acciones y reevaluandolas cada vez. Para que pueda navegar fácilmente a través de todos sus cambios.


Creo que la idea no es tanto "deshacer" como guardar una referencia al árbol de estado completo cada vez que una acción pasa a través de redux.

Tendría una pila de historial compuesta por el estado de la aplicación varias veces.

let history = [state1, state2, state3] // some action happens let history = [state1, state2, state3, state4] // some action happens let history = [state1, state2, state3, state4, state5] // undo an action let history = [state1, state2, state3, state4] state = state4

Para "deshacer" una acción, simplemente reemplace el estado de la aplicación con uno de los estados guardados.

Esto se puede hacer eficiente con las estructuras de datos que respaldan el intercambio estructural, pero en el desarrollo no es necesario que consideremos las limitaciones de recursos demasiado de todos modos.


También quería crear una funcionalidad de deshacer simple, pero ya había enviado una aplicación con almacenamiento redux que serializa y carga el estado para cada usuario. Por lo tanto, para mantenerlo compatible con versiones anteriores, no podría usar ninguna solución que ajuste mis claves de estado, como reduce-deshacer hace con past: [] y present:

Buscando una alternativa, el tutorial de Dan me inspiró para anular los combineReducers . Ahora tengo una parte del estado: history que guarda hasta 10 copias del resto del estado y las muestra en la acción UNDO . Aquí está el código, esto también podría funcionar para su caso:

function shouldSaveUndo(action){ const blacklist = [''@@INIT'', ''REDUX_STORAGE_SAVE'', ''REDUX_STORAGE_LOAD'', ''UNDO'']; return !blacklist.includes(action.type); } function combineReducers(reducers){ return (state = {}, action) => { if (action.type == "UNDO" && state.history.length > 0){ // Load previous state and pop the history return { ...Object.keys(reducers).reduce((stateKeys, key) => { stateKeys[key] = state.history[0][key]; return stateKeys; }, {}), history: state.history.slice(1) } } else { // Save a new undo unless the action is blacklisted const newHistory = shouldSaveUndo(action) ? [{ ...Object.keys(reducers).reduce((stateKeys, key) => { stateKeys[key] = state[key]; return stateKeys; }, {}) }] : undefined; return { // Calculate the next state ...Object.keys(reducers).reduce((stateKeys, key) => { stateKeys[key] = reducers[key](state[key], action); return stateKeys; }, {}), history: [ ...(newHistory || []), ...(state.history || []) ].slice(0, 10) }; } }; } export default combineReducers({ reducerOne, reducerTwo, reducerThree });

Para mí, esto funciona como un encanto, simplemente no se ve muy bonito. Estaría feliz por cualquier comentario si esta es una buena / mala idea y por qué ;-)


¿Hay una forma incorporada en Redux para hacer esto? ¿O tendría que escribir middleware para esto?

Middleware suena como la idea equivocada en este caso porque esto es pura preocupación de la administración del estado. En su lugar, puede escribir una función que tome un reductor y devuelva un reductor, "realzándolo" con el seguimiento del historial de acción en el camino.

Esbocé este enfoque en esta respuesta , y es similar a cómo funciona el redux-undo , excepto que en lugar de almacenar el estado, puede almacenar acciones. (Depende de las compensaciones que desee realizar y de si es importante poder "cancelar" las acciones en un orden diferente del que ocurrieron).