Переглянути джерело

Started redux-saga tutorial.

Tomi Cvetic 8 роки тому
батько
коміт
886143ad59
1 змінених файлів з 93 додано та 0 видалено
  1. 93 0
      LearnRedux/ReduxSagas.md

+ 93 - 0
LearnRedux/ReduxSagas.md

@@ -0,0 +1,93 @@
+# Using Sagas
+<https://redux-saga.github.io/redux-saga/docs/introduction/BeginnerTutorial.html>
+
+* Sagas connect as middleware to a redux store.
+* Sagas run like cuncurrent worker tasks and have to be started for that.
+
+```jsx
+// main.js
+import { createStore, applyMiddleware } from 'redux'
+import createSagaMiddleware from 'redux-saga'
+
+import { rootSaga } from './sagas'
+
+const sagaMiddleware = createSagaMiddleware()
+const store = createStore(
+  reducer,
+  applyMiddleware(sagaMiddleware)
+)
+sagaMiddleware.run(helloSaga)
+```
+
+* Asynchronous actions need to be split into more tasks to the dispatcher, so reducers can always return immediately:
+
+```jsx
+// actions.js
+function increment(payload) {
+    return {
+        type: 'INCREMENT_REQUEST',
+        payload
+    }
+}
+
+// reducers.js
+export default function counter(state = 0, action) {
+    switch (action.type) {
+        case 'INCREMENT_REQUEST':
+            // disable button
+            // print message
+            /* YOU DON'T NEED TO CALL THE FUNCTION HERE.
+            IT'S INTERCEPTED BY THE MIDDLEWARE. */
+            return state
+        case 'INCREMENT_SUCCESS':
+            return state + 1
+        case 'INCREMENT_FAIL':
+            // print error message
+        default:
+            return state
+    }
+}
+
+// sagas.js
+import { call, put, takeEvery } from 'redux-saga/effects'
+
+// Worker
+export function * incrementAsync () {
+    try {
+        const data = yield call(Api.isIncrementOk)
+        yield put({ type: 'INCREMENT_SUCCESS', data })
+    } catch (error) {
+        yield put({ type: 'INCREMENT_FAIL', error})
+    }
+}
+
+// Watcher (intercepts INCREMENT_REQUEST, dispatches INCREMENT_SUCCESS or INCREMENT_FAIL in return.)
+export function * watchIncrementAsync() {
+    yield takeEvery('INCREMENT_REQUEST', incrementAsync)
+}
+
+// export all sagas in parallel
+export default function * rootSaga() {
+    yield takeEvery('INCREMENT_REQUEST')
+    yield takeEvery('DECREMENT_REQUEST')
+}
+```
+
+## Saga helpers
+* Yield 'effects', in 'redux-saga/effects'
+* `takeEvery` handles every action of a type that is dispatched.
+* Allows multiple `incrementAsync` instances to be started concurrently.
+* `takeLatest` in contrast only takes the response of the latest requested action.
+* Allows only one `incrementAsync` to run at a time
+* If another task is requested, the previous is automatically cancelled.
+* You can start multiple sagas which behave like they were forked.
+
+## Declarative effects
+* Effects are plain JavaScript objects expressing Saga logic.
+* they contain information to be interpreted by the middleware.
+* Sagas can yield effects in multiple forms, the easiest are promises
+* Use `call` to call functions. Call returns on object describing to the middleware what to do. This is similar to action creators, which describe actions for the reducer.
+* For testing, you can just check whether the effect object ist correct, you don't need to actually call the async function.
+    - <https://redux-saga.github.io/redux-saga/docs/basics/DeclarativeEffects.html>
+
+## Dispathing actions to the store