Skip to content

Instantly share code, notes, and snippets.

@ismasan
Created June 13, 2017 22:05
Show Gist options
  • Select an option

  • Save ismasan/952bb09d53569f1bd9f694dd53d8738c to your computer and use it in GitHub Desktop.

Select an option

Save ismasan/952bb09d53569f1bd9f694dd53d8738c to your computer and use it in GitHub Desktop.
Toy Flux store for React or Preact apps
/* The store
yes yes technically this *does* mutate state, but it's functionally the same
Usage:
let initialState = {
todos: []
}
store = new Store({
// The initial state of things
state: initialState,
// Commands do async things and call #commit() to run actual state mutations
commands: {
createTodo(context, data) {
api.post("/todos", data).then((r) => {
context.commit("todoCreated", r)
})
}
},
// Mutations update the state and trigger onChange event
mutations: {
todoCreated(state, todo) {
state.todos = state.todos.concat([todo])
}
}
})
// Hook it up to your React/Preact containers
componentWillMount() {
// start with store's initial state
this.setState(this.props.store.state)
// subscribe to state changes
this.props.store.onChange((state) => {
this.setState(state)
})
}
// Initiate container
render(<Container store={store} />, document.getElementById('root'));
// Issue async commands...
store.command('createTodo', {name: "do something"})
// ... or commit mutations directly
store.commit('todoCreated', {name: "do something", id: 123})
// In your container component you can wrap store methods to use as DOM event handlers
*/
class Store {
constructor({state, commands, mutations}) {
this.state = state || {}
this.commands = commands || {}
this.mutations = mutations || {}
this._subscribers = []
}
command(type, ...payload) {
const cmd = this.commands[type]
if(cmd) {
cmd(this, ...payload)
} else {
console.log(`store: no command for ${type}. args ${payload}`)
}
}
commit(type, ...payload) {
const m = this.mutations[type]
if(m) {
console.log(`store: mutation for ${type}. args ${payload}`)
m(this.state, ...payload)
this.publish(this.state)
} else {
console.log(`store: no mutation for ${type}. args ${payload}`)
}
}
onChange(fn) {
this._subscribers.push(fn)
}
publish(state) {
this._subscribers.forEach(sub => sub(state))
}
}
export default Store
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment