Skip to content

Instantly share code, notes, and snippets.

@craigtaub
Last active August 23, 2017 10:37
Show Gist options
  • Select an option

  • Save craigtaub/841fa903454efa4a256cbea8c7635832 to your computer and use it in GitHub Desktop.

Select an option

Save craigtaub/841fa903454efa4a256cbea8c7635832 to your computer and use it in GitHub Desktop.
WIP - Vanilla Redux Sagas
// -------- 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