Last active
August 23, 2017 10:37
-
-
Save craigtaub/841fa903454efa4a256cbea8c7635832 to your computer and use it in GitHub Desktop.
WIP - Vanilla Redux Sagas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // -------- declaration of Store -------- -------- | |
| const runUntilDone = (iterator) => { | |
| if (!iterator.next().done) { | |
| runUntilDone(iterator); | |
| } | |
| } | |
| function createStore(reducers, sagas) { | |
| let currentSubscribers = []; | |
| const dispatch = (action) => { | |
| if (sagas[action.type]) { | |
| runUntilDone(sagas[action.type]) | |
| } | |
| const currentState = reducers[action.type](currentState, action); | |
| for (let i = 0; i < currentSubscribers.length; i++) { | |
| currentSubscribers[i](currentState); | |
| } | |
| } | |
| const subscribe = (subscriber) => { | |
| currentSubscribers = [...currentSubscribers, subscriber]; | |
| } | |
| return { | |
| dispatch, subscribe | |
| } | |
| } | |
| // -------- reducers -------- -------- -------- -------- | |
| const defaultState = {}; | |
| const reducers = { | |
| ['FIRST_ACTION']: (state = defaultState, action) => { | |
| const newState = Object.assign({}, state, action); | |
| return newState.payload; | |
| }, | |
| ['SECOND_ACTION']: (state = defaultState, action) => { | |
| const newState = Object.assign({}, state, action); | |
| return newState.payload; | |
| }, | |
| ['FETCH_SUCCESS']: (state = defaultState, action) => { | |
| const newState = Object.assign({}, state, action); | |
| return newState.payload; | |
| }, | |
| } | |
| // -------- actions -------- -------- | |
| const myFirstAction = (data) => ({ | |
| type: 'FIRST_ACTION', | |
| payload: data | |
| }); | |
| const mySecondAction = (data) => ({ | |
| type: 'SECOND_ACTION', | |
| payload: data | |
| }); | |
| const successAction = (data) => ({ | |
| type: 'FETCH_SUCCESS', | |
| payload: data | |
| }) | |
| // -------- declare sagas + watchers + workers -------- -------- -------- -------- | |
| function createEffects(store) { | |
| const put = (action) => { | |
| store.dispatch(action); | |
| } | |
| const call = (promise) => { | |
| // console.log(promise) | |
| return promise().then(data => { | |
| console.log('data'); | |
| }); | |
| } | |
| return { put, call } | |
| } | |
| const sagas = {}; | |
| function * takeLatest (action, generator) { | |
| sagas[action] = generator(); | |
| } | |
| function makeRequest() { | |
| return Promise.resolve('API Data'); | |
| } | |
| function* successWorker(effects) { | |
| yield effects.put(mySecondAction('via-saga-two')); | |
| } | |
| // workers: perform requested task | |
| function* firstWorker(effects) { | |
| const data = yield effects.call(makeRequest); | |
| yield effects.put(successAction(data)); | |
| } | |
| //watchers, watch actions + coordinate workers | |
| function * watchRunFirstSaga(effects) { | |
| yield* takeLatest('FIRST_ACTION', firstWorker.bind(this, effects)); | |
| } | |
| function * watchFetchSuccess(effects) { | |
| yield* takeLatest('FETCH_SUCCESS', successWorker.bind(this, effects)); | |
| } | |
| function* root(effects) { | |
| yield [ | |
| watchRunFirstSaga(effects), | |
| watchFetchSuccess(effects) | |
| ] | |
| } | |
| // -------- create component -------- -------- -------- -------- | |
| const MyComponent = (props) => { | |
| console.log('component, prop:', props) | |
| } | |
| // -------- create store, subscribe + dispatch -------- -------- -------- | |
| const store = createStore(reducers, sagas); | |
| const effects = createEffects(store); | |
| store.subscribe(MyComponent) | |
| // Redux via sagas | |
| const iterator = root(effects); | |
| const items = iterator.next().value; | |
| items.map(item => item.next()); // setup all workers; | |
| store.dispatch(myFirstAction('via-one-action')) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment