Estoy tratando de realizar varios cambios en la tienda, pero no renderizar hasta que se hayan realizado todos los cambios. Quería hacer esto con redux-thunk.
Aquí está mi creador de acciones:
function addProp(name, value) { return { type:'ADD_PROP', name, value } } function multiGeoChanges(...changes) { // my goal here is to make multiple changes to geo, and make sure that react doesnt update the render till the end return async function(dispatch, getState) { for (let change of changes) { dispatch(change); await promiseTimeout(2000); } } }Envío mi creador de acciones asíncronas de esta manera:
store.dispatch(multiGeoChanges(addProp(1, "val1"), addProp(2, "val2"), addProp(3, "val3"))); Sin embargo, esto provoca que la reacción se reproduzca después de cada dispatch . Soy nuevo en redux-thunk, nunca usé middleware asíncrono, pero pensé que podría ayudarme aquí.
La respuesta de @Kokovin Vladislav es correcta. Para agregar algo de contexto adicional:
Redux notificará a todos los suscriptores después de cada envío. Para reducir las re-renderizaciones, envíe menos veces o use uno de los varios enfoques para "agrupar" envíos y notificaciones. Para obtener más información, consulte las preguntas frecuentes de Redux sobre eventos de actualización: http://redux.js.org/docs/faq/Performance.html#performance-update-events .
También escribí recientemente un par de publicaciones de blog que se relacionan con este tema. Idiomatic Redux: Thoughts on Thunks, Sagas, Abstraction, and Reusability analiza los pros y los contras del uso de thunks y resume varias formas de manejar el procesamiento por lotes de despachos. Parte práctica de Redux 6: Listas conectadas, formularios y rendimiento describe varios aspectos clave a tener en cuenta con respecto al rendimiento de Redux.
Finalmente, hay varias otras bibliotecas que pueden ayudar a agrupar las notificaciones de cambio de tienda. Consulte la sección Store#Store Change Subscriptions de mi catálogo de complementos de Redux para obtener una lista de complementos relevantes. En particular, podría estar interesado en https://github.com/manaflair/redux-batch , que le permitirá enviar una serie de acciones con un solo evento de notificación.
Hay formas de lograr el objetivo:
Forma clásica:
por lo general: las acciones describen el hecho de que algo sucedió , pero no especifican cómo cambia el estado de la aplicación en respuesta. Este es el trabajo de los reductores. Eso también significa que las acciones no son setters .
Por lo tanto, podría describir lo que sucedió y acumular cambios, y enviar una acción como:
const multipleAddProp = (changedProps) =>({ type:'MULTIPLE_ADD_PROP', changedProps });Y luego reaccionar sobre la acción en el reductor:
const geo=(state,action)=>{ ... switch (action.type){ case 'MULTIPLE_ADD_PROP': // apply new props ... } }Otra forma Cuando la renderización es crítica:
entonces puede considerar limitar los componentes, que podrían volver a generarse en el cambio de estado. Por ejemplo, puede usar shouldComponentUpdate para verificar si el componente debe renderizarse o no. También puede usar reseleccionar , para no volver a renderizar los componentes conectados después de calcular los datos derivados...
Forma no estándar: redux-batch-action
Funciona algo así como transacción.
En este ejemplo, los suscriptores serían notificados una vez:
import { batchActions } from 'redux-batched-actions'; const multiGeoChanges=(...arrayOfActions)=> dispatch => { dispatch( batchActions(arrayOfActions) ); }En react-redux 7.0.1+, el procesamiento por lotes ahora está integrado. Notas de la versión 7.0.1:
https://github.com/reduxjs/react-redux/releases/tag/v7.0.1
Actualizaciones por lotes
React tiene una API unstable_batchedUpdates que utiliza para agrupar varias actualizaciones del mismo ciclo de eventos. El equipo de React nos animó a usar esto y actualizamos nuestro manejo interno de suscripciones de Redux para aprovechar esta API. Esto también debería ayudar a mejorar el rendimiento, al reducir la cantidad de representaciones distintas causadas por una actualización de la tienda Redux.
function myThunk() { return (dispatch, getState) => { // should only result in one combined re-render, not two batch(() => { dispatch(increment()); dispatch(increment()); }) } }