Last active
December 28, 2020 07:50
-
-
Save kigawas/237415a4f7b7eda95f9de176e2434387 to your computer and use it in GitHub Desktop.
redux in 40 lines of code with redo/undo
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
const createStore = (reducer) => { | |
const states = [reducer()]; | |
let sp = 0; // stack pointer | |
const listeners = new Set(); | |
function notify() { | |
for (const listener of listeners) { | |
listener(); | |
} | |
} | |
function max(a, b) { | |
return a > b ? a : b; | |
} | |
function min(a, b) { | |
return a < b ? a : b; | |
} | |
return { | |
getState() { | |
return states[sp]; | |
}, | |
redo() { | |
sp = min(sp + 1, states.length - 1); | |
notify(); | |
}, | |
undo() { | |
sp = max(sp - 1, 0); | |
notify(); | |
}, | |
dispatch(action) { | |
const newState = reducer(this.getState(), action); | |
sp += 1; | |
if (sp === states.length) { | |
states.push(newState); | |
} else { | |
states[sp] = newState; | |
} | |
notify(); | |
}, | |
subscribe(listener) { | |
listeners.add(listener); | |
}, | |
}; | |
}; | |
const countStore = createStore((state = { count: 0 }, action = { type: "" }) => { | |
switch (action.type) { | |
case "INCREASE_COUNT": | |
return { count: state.count + action.count }; | |
default: | |
return state; | |
} | |
}); | |
countStore.subscribe(() => { | |
// handler A | |
const { count } = countStore.getState(); | |
console.log("A count:", count); | |
}); | |
countStore.subscribe(() => { | |
// handler B | |
const { count } = countStore.getState(); | |
console.log("B count:", count); | |
}); | |
const increase = (n) => { | |
console.log("increase:", n); | |
countStore.dispatch({ type: "INCREASE_COUNT", count: n }); | |
}; | |
const undo = () => { | |
console.log("undo:"); | |
countStore.undo(); | |
} | |
const redo = () => { | |
console.log("redo:"); | |
countStore.redo(); | |
} | |
increase(1); | |
increase(3); | |
undo(); | |
redo(); | |
redo(); | |
increase(-1); | |
increase(-3); | |
undo(); | |
increase(1); | |
redo(); | |
increase(3); | |
undo(); | |
undo(); | |
undo(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment