Skip to content

Instantly share code, notes, and snippets.

@cyio
Created August 24, 2020 07:41
Show Gist options
  • Save cyio/627a6bbe5a3eb3c43a6630804568c59e to your computer and use it in GitHub Desktop.
Save cyio/627a6bbe5a3eb3c43a6630804568c59e to your computer and use it in GitHub Desktop.

Revisions

  1. cyio created this gist Aug 24, 2020.
    111 changes: 111 additions & 0 deletions learn-saga.diff
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,111 @@
    diff --git a/Counter.js b/Counter.js
    index 04222ed..ca97297 100644
    --- a/Counter.js
    +++ b/Counter.js
    @@ -1,8 +1,12 @@
    /*eslint-disable no-unused-vars */
    import React, { Component, PropTypes } from 'react'

    -const Counter = ({ value, onIncrement, onDecrement }) =>
    +const Counter = ({ value, onIncrement, onDecrement, onIncrementAsync }) =>
    <div>
    + <button onClick={onIncrementAsync}>
    + Increment after 1 second
    + </button>
    + {' '}
    <button onClick={onIncrement}>
    Increment
    </button>
    diff --git a/main.js b/main.js
    index e9cdd5f..3f7abf7 100644
    --- a/main.js
    +++ b/main.js
    @@ -3,11 +3,18 @@ import "babel-polyfill"
    import React from 'react'
    import ReactDOM from 'react-dom'
    import { createStore, applyMiddleware } from 'redux'
    +import createSagaMiddleware from 'redux-saga'

    import Counter from './Counter'
    import reducer from './reducers'
    +import rootSaga from './sagas'

    -const store = createStore(reducer)
    +const sagaMiddleware = createSagaMiddleware()
    +const store = createStore(
    + reducer,
    + applyMiddleware(sagaMiddleware)
    +)
    +sagaMiddleware.run(rootSaga)

    const action = type => store.dispatch({type})

    @@ -16,6 +23,7 @@ function render() {
    <Counter
    value={store.getState()}
    onIncrement={() => action('INCREMENT')}
    + onIncrementAsync={() => action('INCREMENT_ASYNC')}
    onDecrement={() => action('DECREMENT')} />,
    document.getElementById('root')
    )
    diff --git a/sagas.js b/sagas.js
    new file mode 100644
    index 0000000..99d6bda
    --- /dev/null
    +++ b/sagas.js
    @@ -0,0 +1,21 @@
    +import { put, call, takeEvery, takeLatest, all } from 'redux-saga/effects'
    +
    +export const delay = (ms) => new Promise(res => setTimeout(res, ms))
    +
    +// worker
    +export function* incrementAsync() {
    + yield call(delay, 1000)
    + yield put({ type: 'INCREMENT' })
    +}
    +
    +// watcher
    +export function* watchIncrementAsync() {
    + yield takeEvery('INCREMENT_ASYNC', incrementAsync)
    +}
    +
    +export default function* rootSaga() {
    + yield all([
    + // incrementAsync(),
    + watchIncrementAsync(),
    + ])
    +}
    diff --git a/sagas.spec.js b/sagas.spec.js
    new file mode 100644
    index 0000000..f937166
    --- /dev/null
    +++ b/sagas.spec.js
    @@ -0,0 +1,28 @@
    +import test from 'tape'
    +
    +import { put, call } from 'redux-saga/effects'
    +import { incrementAsync, delay } from './sagas'
    +
    +test('incrementAsync Saga test', (assert) => {
    + const gen = incrementAsync()
    +
    + assert.deepEqual(
    + gen.next().value,
    + call(delay, 1000),
    + 'incrementAsync Saga must call delay(1000)'
    + )
    +
    + assert.deepEqual(
    + gen.next().value,
    + put({ type: 'INCREMENT' }),
    + 'incrementAsync Saga must dispatch an INCREMENT action'
    + )
    +
    + assert.deepEqual(
    + gen.next(),
    + { done: true, value: undefined },
    + 'incrementAsync Saga must be done'
    + )
    +
    + assert.end()
    +})