Skip to content

Instantly share code, notes, and snippets.

@eisisig
Forked from gaearon/combining.js
Created April 1, 2016 09:12
Show Gist options
  • Save eisisig/b4995843fbba62ed3eec1af961c945ff to your computer and use it in GitHub Desktop.
Save eisisig/b4995843fbba62ed3eec1af961c945ff to your computer and use it in GitHub Desktop.
Combining Stateless Stores
// ------------
// counterStore.js
// ------------
import {
INCREMENT_COUNTER,
DECREMENT_COUNTER
} from '../constants/ActionTypes';
const initialState = { counter: 0 };
function increment({ counter }) {
return { counter: counter + 1 };
}
function decrement({ counter }) {
return { counter: counter - 1 };
}
export default function counterStore(state = initialState, action) {
switch (action.type) {
case INCREMENT_COUNTER:
return increment(state, action);
case DECREMENT_COUNTER:
return decrement(state, action);
default:
return state;
}
}
// ------------
// todoStore.js
// ------------
import { ADD_TODO } from '../constants/ActionTypes';
const initialState = {
todos: [{
text: 'do something',
id: 0
}]
};
export default function todoStore(state = initialState, action) {
switch (action.type) {
case ADD_TODO:
return {
todos: [{
id: state.todos[0].id + 1,
text: action.text
}].concat(state.todos)
};
}
return state;
}
// ------------
// combinedStore.js
// ------------
// Let's say at some point I know that these stores depend on each other in some way.
// If I *decide* I want to hide these stores as impl details of a single store
// I don't need to change their public APIs at all. I just register combinedStore instead.
import counterStore from './counterStore';
import todoStore from '../todoStore';
const initialState = {
counterData: undefined,
todoData: undefined
};
export default function combinedStore(state = initialState, action) {
const counterData = counterStore(state.counterData, action);
const todoData = todoStore(state.todoData, action);
return { counterData, todoData };
}
// So it's trivial to "merge" stores but keep the delegation. This is exactly how Elm models work too.
// Now, if I *want* to, I can make substores more custom (e.g. make a store factory that responds only to
// actions matching predicate, like createFollowersStore(userId) => FollowersStore that responds to specific
// userId in the action). Composition all the way!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment