Skip to content

Instantly share code, notes, and snippets.

@SeedyROM
Created September 27, 2019 08:35
Show Gist options
  • Save SeedyROM/70776583af0bf765ab696a15d4d89b50 to your computer and use it in GitHub Desktop.
Save SeedyROM/70776583af0bf765ab696a15d4d89b50 to your computer and use it in GitHub Desktop.
A simple recreation of a SUPER basic redux store.
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