Created
April 23, 2019 21:49
-
-
Save keller/4e2d884f1865db4153792069310ac57c to your computer and use it in GitHub Desktop.
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
/* naive implementation of useState and useEffect */ | |
let states = []; | |
let newStates; | |
let _render = () => {}; | |
let unsubs = []; | |
let deps = []; | |
let newDeps; | |
const shallowEqual = (a, b) => | |
a.length === b.length && a.every((e, i) => e === b[i]); | |
function useState(initial) { | |
let state = states.pop(); | |
if (state === undefined) { | |
state = [initial]; | |
} | |
newStates.push(state); | |
const setState = newState => { | |
state[0] = newState; | |
_render(); | |
} | |
return [state[0], setState]; | |
} | |
function useEffect(effect, effectDeps) { | |
const dep = deps.pop(); | |
if (dep == null || effectDeps == null || (effectDeps.length > 0 && !(shallowEqual(effectDeps, dep)))) { | |
const unsub = effect(); | |
if (unsub) { | |
unsubs.push(unsub); | |
} | |
} | |
newDeps.push(effectDeps); | |
} | |
function render(app) { | |
_render = () => { | |
unsubs.forEach(unsub => unsub()); | |
unsubs = []; | |
newStates = []; | |
newDeps = []; | |
app(); | |
states = newStates; | |
deps = newDeps; | |
}; | |
_render(); | |
} | |
/* the app */ | |
function app() { | |
const [count, setCount] = useState(0); | |
const [count2, setCount2] = useState(0); | |
useEffect(() => { | |
const button = document.querySelector("button"); | |
const onClick = () => { | |
setCount(count+1); | |
setCount2(count2+2); | |
} | |
button.addEventListener("click", onClick); | |
return () => { | |
button.removeEventListener("click", onClick); | |
} | |
}, [count, count2]); | |
const el1 = document.querySelector(".count1"); | |
const el2 = document.querySelector(".count2"); | |
el1.innerText = count; | |
el2.innerText = count2; | |
} | |
/* render it */ | |
render(app); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment