Last active
August 15, 2019 01:38
-
-
Save anthonybrown/fb1bedd72b95f534622a5a477a93d680 to your computer and use it in GitHub Desktop.
Using closures, higher order functions to have a stateful function
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
function getAdd() { | |
let foo = 0; | |
return function() { | |
foo = foo + 1; | |
return foo; | |
}; | |
} | |
const add = getAdd() | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); |
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
const add = (function getAdd() { | |
let foo = 0; | |
return function() { | |
foo = foo + 1; | |
return foo; | |
}; | |
}()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); | |
console.log(add()); |
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
// basically creating a react component in JavaScript | |
const React = (function() { | |
let _val; | |
function useState(initVal) { | |
const state = _val || initVal; | |
const setState = newVal => { | |
_val = newVal; | |
}; | |
return [state, setState]; | |
} | |
function render(Component) { | |
const C = Component(); | |
C.render(); | |
return C; | |
} | |
return { useState, render }; | |
})(); | |
function Component() { | |
const [count, setCount] = React.useState(1); | |
return { | |
render: () => console.log(count), | |
click: () => setCount(count + 1), | |
}; | |
} | |
var App = React.render(Component); | |
App.click(); | |
var App = React.render(Component); | |
App.click(); | |
var App = React.render(Component); | |
App.click(); | |
var App = React.render(Component); | |
App.click(); | |
var App = React.render(Component); | |
// console.log(count()); | |
// setCount(2); | |
// console.log(count()); |
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
const React = (function() { | |
let hooks = []; | |
let idx = 0; | |
function useState(initVal) { | |
const state = hooks[idx] || initVal; | |
const _idx = idx; | |
const setState = newVal => { | |
hooks[_idx] = newVal; | |
}; | |
idx++; | |
return [state, setState]; | |
} | |
function render(Component) { | |
idx = 0; | |
const C = Component(); | |
C.render(); | |
return C; | |
} | |
function useEffect(cb, depArray) { | |
const oldDeps = hooks[idx]; | |
let hasChanged = true; | |
if (oldDeps) { | |
hasChanged = depArray.some((dep, i) => !Object.is(dep, oldDeps[i])); | |
} | |
// detect change | |
if (hasChanged) cb(); | |
hooks[idx] = depArray; | |
idx++; | |
} | |
return { useState, render, useEffect }; | |
})(); | |
function Component() { | |
// we have 2 hooks now | |
const [count, setCount] = React.useState(1); | |
const [text, setText] = React.useState('apple'); | |
React.useEffect(() => { | |
console.log('use effect hook FTW!!!'); | |
}, []); // if I leave the empty array, it only runs once at the start | |
// if I put in [count] it updates from 1 to 2 | |
// if I put in ['pear'] it updates when the text updates from 'apple' to 'pear' | |
// and if I delete the array, it runs every single time. | |
return { | |
// just for simulating since we don't have a button or working with the DOM | |
render: () => console.log({ count, text }), | |
click: () => setCount(count + 1), | |
type: word => setText(word), | |
}; | |
} | |
var App = React.render(Component); | |
App.click(); | |
var App = React.render(Component); | |
App.type('pear'); | |
var App = React.render(Component); |
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
iconst React = (function() { | |
let hooks = []; | |
let idx = 0; | |
function useState(initVal) { | |
const state = hooks[idx] || initVal; | |
const _idx = idx; | |
const setState = newVal => { | |
hooks[_idx] = newVal; | |
}; | |
idx++; | |
return [state, setState]; | |
} | |
function render(Component) { | |
idx = 0; | |
const C = Component(); | |
C.render(); | |
return C; | |
} | |
return { useState, render }; | |
})(); | |
function Component() { | |
// we have 2 hooks now | |
const [count, setCount] = React.useState(1); | |
const [text, setText] = React.useState('apple'); | |
return { | |
// just for simulating since we don't have a button or working with the DOM | |
render: () => console.log({ count, text }), | |
click: () => setCount(count + 1), | |
type: word => setText(word), | |
}; | |
} | |
var App = React.render(Component); | |
App.click(); | |
var App = React.render(Component); | |
App.type('pear'); | |
var App = React.render(Component); | |
/** | |
* We now have 2 independent states in our code | |
* 1 to update the count and | |
* 2 to update the text | |
*/ |
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
function useState(initVal) { | |
let _val = initVal; | |
const state = () => _val; | |
const setState = newVal => { | |
_val = newVal; | |
}; | |
return [state, setState]; | |
} | |
const [count, setCount] = useState(1); | |
console.log(count()); | |
setCount(2); | |
console.log(count()); | |
setCount(3); | |
console.log(count()); |
The functions are out of order, but basically the longer the function is the order.
Meaning the shortest code is the start and the longest is the most recent.
¯_(ツ)_/¯
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
From "Getting Closure on React Hooks" by Shawn Wang