Created
June 13, 2017 22:05
-
-
Save ismasan/952bb09d53569f1bd9f694dd53d8738c to your computer and use it in GitHub Desktop.
Toy Flux store for React or Preact apps
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
| /* 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