useMemo in React naive implementation
by de Montalembert Jonathan
JavaScript
const React = (function() {
let currentHook = 0,
hooks = []
function memo(fn, deps) {
const localHook = currentHook
hooks[localHook] = hooks[localHook] || []
currentHook++
if (!hooks[localHook].length) {
return compute()
} else {
const found = hooks[localHook].find((memoized) => {
return memoized.slice(0, deps.length).every((m, i) => m === deps[i])
})
if (found) {
console.log('from cache', found.slice(-1)[0])
return found.slice(-1)[0]
} else {
return compute()
}
}
function compute() {
console.log('compute')
const newOutput = fn.apply(null, deps)
hooks[localHook] = [...hooks[localHook],
[...deps, newOutput]
]
return newOutput
}
}
return {
useMemo: memo,
useCallback: (fn, deps) => memo(() => fn, deps),
render: (Component) => {
const inst = Component()
currentHook = 0
inst.render();
console.log("hooks", hooks)
}
}
})()
function sum(a, b) {
return a + b
}
function View(b) {
let a = 1, c = 9
const memoized = React.useMemo(sum, [a, b])
const memoized2 = React.useMemo(sum, [c, b])
const callback = React.useCallback(() => sum(a, b), [a, b])
return {
render: () => {
console.log('render', memoized, memoized2, callback())
}
}
}
React.render(View.bind(null, 2))
React.render(View.bind(null, 3))
React.render(View.bind(null, 2))