Para ejecutar muchas instrucciones de sincronización una tras otra y también mantener la legibilidad del código, podemos enviar una acción que luego desencadenará una saga. Podemos usar la biblioteca de redux-saga de la misma manera. Usando la saga, podemos despachar acciones con el efecto «put».
Para instalar la biblioteca, usamos el siguiente código:
1npm install redux-saga
javascript
Abajo está el JS de nuestro componente:
12345678910// my-sagas.jsimport{ put }from$0027redux-saga/effects$0027;import{ sendMsg, setLoading, navigateTo }from$0027. /acciones$0027;exportfunction*sendMsg(action){yieldput(setLoading($0027sendMsgPage$0027,true));yieldput(sendMsg(action.payload.message));yieldput(navigateTo({routeName:$0027myMsgList$0027}));yieldput(setLoading($0027sendMsgPage$0027,false));}
javascript
A continuación se muestra otro ejemplo de cómo hacer llamadas de sincronización utilizando saga.
Crearemos una Saga básica:
123exportfunction*heySaga(){console.log($0027Hola desde un ejemplo básico de Sagas!$0027)}
javascript
A continuación está nuestra principal..:
1234567891011121314151617// ...import{ createStore, applyMiddleware }from$0027redux$0027import createSagaMiddleware from$0027redux-saga$0027// ...import{ heySaga }from$0027. /sagas$0027const sagaMiddleware =createSagaMiddleware()const store =createStore( reducx,applyMiddleware(sagaMiddleware))sagaMiddleware.run(heySaga)constaction=type= > store.dispatch({type})// rest
javascript
Y abajo está nuestro contra-ejemplo que muestra las llamadas de sincronización:
123456789101112131415161718constMyCounter=(valor, onInc, onDec, onIncAsync })=;<div><botón onClick={onIncAsync};Incremento después de 1 segundo botón onClick={onInc}{onInc};Incremento</botón&<}<botón onClick={onDec}{onDec};Disminución</botón&&&hr /div javascriptLuego conectaremos el onIncAsync de nuestro Componente de Reacción a la acción de Almacenar. Actualizaremos el módulo main.js como se muestra a continuación:
12345678910functionrender(){ReactDOM.render(<MyCounter value={store. getState()} onInc={()= >action($0027INC$0027)} onDec={()=§;action($0027DEC$0027)} onIncAsync={()=§;action($0027INC_ASYNC$0027)}/§;,document.getElementById($0027root$0027))}javascript
A diferencia de la reducción de pensamiento, nuestro componente aquí envía una acción de objeto simple. Añadiremos el siguiente código en sagas.js:
123456789101112131415import{ put, takeEvery }from$0027redux-saga/effects$0027constdelay=(ms)={nuevoPromise(response=§;setTimeout(response, ms))// ... // Nuestro trabajador de Saga realizaría la tarea async inc taskexportfunction*incAsync(){yielddelay(2000)yieldput({ tipo:$0027INC$0027})}// Nuestro vigilante de Saga generaría una nueva tarea incAsync en cada INC_ASYNCexportfunction*watchIncAsync(){yieldtakeEvery($0027INC_ASYNC$0027, incAsync)}javascript
Las sagas se implementan generalmente usando funciones de generador, que ceden objetos a nuestro middleware de redux-saga. Los objetos cedidos son como instrucciones que deben ser interpretadas por nuestro middleware. Cuando cedemos una promesa a nuestro middleware, éste suspenderá la saga hasta el momento en que se complete la promesa. Según el código anterior, la saga incAsync se suspende hasta que se resuelva la promesa que se devuelve por retraso, lo que sucedería después de 2 segundos.
Una vez que resolvamos la promesa, nuestro middleware reanudará la Saga y ejecutará el código hasta el próximo rendimiento. En nuestro ejemplo, la siguiente declaración es otro objeto cedido, es decir, el resultado de llamar a put({tipo: $0027INC$0027}), instruyendo así a nuestro middleware para enviar una acción INC.
En el ejemplo anterior, "poner" puede ser llamado como un "efecto". Los efectos son simples objetos JS que tienen instrucciones que deben ser cumplidas por nuestro middleware. Cuando nuestro middleware recupera un efecto producido por una saga, la saga se detiene hasta que el efecto se completa.
Así, en resumen, la Saga IncAsync duerme durante 2 segundos a través de la llamada a la demora(2000). Luego envía una acción INC.
También hemos creado otra saga, watchIncAsync. Usamos la función de ayuda "takeEvery" proporcionada por la librería redux-saga para escuchar las acciones de INC_ASYNC enviadas y ejecutar "incAsync" cada vez.
Tenemos dos sagas ahora, y tenemos que empezar ambas inmediatamente. Para ello, añadiremos una saga principal que se encargará de iniciar nuestras otras sagas. Actualizaremos el código en sagas.js como se muestra a continuación:
12345678910111213141516171819202122232425import{ put, takeEvery, all }from$0027redux-saga/effects$0027constdelay=(ms)=>newPromise(response=§;setTimeout(response, ms))function*heySaga(){console.log($0027¡Hola desde un ejemplo básico de Sagas! $0027);}function*incAsync(){yielddelay(2000)yieldput({tipo: $0027INC$0027})}function*watchIncAsync(){yieldtakeEvery($0027INC_ASYNC$0027, incAsync)}// puedes ver que sólo exportamos la Saga principal// Este es el único punto de entrada para iniciar todas nuestras sagas inmediatamente después de exportar la función por defecto*mainSaga(){yieldall([heySaga(),watchIncAsync()])}javascript
Esta saga produciría una matriz que contendría los resultados de llamar a las dos sagas; heySaga y watchIncAsync. Así, los dos generadores resultantes se pondrían en marcha en paralelo. Ahora sólo necesitamos llamar a sagaMiddleware.run en la saga principal en main.js.
12345678910111213// ...importar mainSaga desde$0027./sagas$0027s const sagaMiddleware =createSagaMiddleware()const store =createStore( reducer,applyMiddleware(sagaMiddleware))sagaMiddleware.run(rootSaga)constaction=type=> store.dispatch({type})// restjavascript