Created
September 27, 2019 08:35
-
-
Save SeedyROM/70776583af0bf765ab696a15d4d89b50 to your computer and use it in GitHub Desktop.
A simple recreation of a SUPER basic redux store.
This file contains 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
class Store { | |
constructor(reducer) { | |
const [state, dispatch] = reducer; | |
this.state = Object.freeze(state); | |
this._dispatch = dispatch; | |
this._effectFunc = null; | |
} | |
dispatch(action) { | |
const prevState = Object.freeze({ ...this.state }); | |
this.state = Object.freeze(this._dispatch(this.state, action)); | |
if (this._effectFunc) this._effectFunc(this.state, prevState); | |
} | |
effect(effectFunc) { | |
this._effectFunc = effectFunc; | |
} | |
} | |
// Pull the wool over your functional eyes. | |
const createStore = reducer => { | |
return new Store(reducer); | |
}; | |
// Return our state and dispatch function | |
const createReducer = (initialState, reducer) => { | |
return [initialState, (state, action) => reducer(state, action)]; | |
}; | |
// Our reducer function | |
const countReducer = (state, action) => { | |
switch (action) { | |
case "inc": | |
return { | |
...state, | |
count: state.count + 1 | |
}; | |
case "dec": | |
return { | |
...state, | |
count: state.count - 1 | |
}; | |
default: | |
return state; | |
} | |
}; | |
// Create the reducer | |
const [state, dispatch] = createReducer( | |
{ | |
count: 0 | |
}, | |
countReducer | |
); | |
// How to increment twice without reducing! Ouch! | |
// console.log(dispatch(dispatch(state, "inc"), "inc")); | |
// Reduce! over our actions and get a valid state | |
const actions = ["inc", "inc", "dec", "dec", "inc"]; | |
const newState = actions.reduce( | |
(state, action) => dispatch(state, action), | |
state | |
); | |
// How to use our class Store | |
const store = createStore( | |
createReducer({ count: 0, hello: true }, countReducer) | |
); | |
document.querySelector("#app").innerText = store.state.count; | |
store.effect((state, prevState) => { | |
document.querySelector("#app").innerText = state.count; | |
}); | |
document.querySelector("#inc").addEventListener("click", () => { | |
store.dispatch("inc"); | |
}); | |
document.querySelector("#dec").addEventListener("click", () => { | |
store.dispatch("dec"); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment