Skip to content

Instantly share code, notes, and snippets.

@dptole
Last active February 25, 2020 06:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dptole/6fe35d6939d269050ba16fb4a898f547 to your computer and use it in GitHub Desktop.
Save dptole/6fe35d6939d269050ba16fb4a898f547 to your computer and use it in GitHub Desktop.
Hooks & Effects in React
// https://reactjs.org/docs/hooks-intro.html
// https://reactjs.org/docs/hooks-overview.html
// https://reactjs.org/docs/hooks-state.html
// https://reactjs.org/docs/hooks-effect.html
// https://reactjs.org/docs/hooks-rules.html
// https://reactjs.org/docs/hooks-custom.html
// https://reactjs.org/docs/hooks-reference.html
const createActions = model => {
const actions = {
ADD_CLICKED_ASYNC: async event => {
model.thinking.update(old_think => true)
},
ADD_CLICKED: () => {
model.count.update(old_count => old_count + 1)
},
RESTART: () => {
for(const prop in model)
model[prop].update(model[prop].init_value)
},
UNMOUNT: () => {
model.count.update(0)
model.visible.update(false)
document.title = 'Unmounted'
}
}
return actions
}
const initModel = () =>
[
// <name of the field>, <initial value>
['count' , 0],
['thinking' , false],
['visible' , true]
].reduce((model, [name, init_value]) => {
const [value, update] = React.useState(init_value)
model[name] = {value, update, init_value}
return model
}, {})
const Example = () => {
const model = initModel()
const actions = createActions(model)
window.example = {model, actions}
React.useEffect(() => {
if(model.visible.value)
document.title = 'Clicks: ' + model.count.value
if(model.thinking.value === true)
setTimeout(() => {
model.thinking.update(old_think => false)
if(model.visible.value)
actions.ADD_CLICKED()
}, 400 + Math.random() * 1e3)
return () => {
if(model.count.value >= 10)
actions.UNMOUNT()
}
})
if(model.visible.value === false)
return (
<div>
<div>Too many clicks!</div>
<div><button onClick={actions.RESTART}>Restart</button></div>
</div>
);
return (
<div>
<p>You clicked {model.count.value} times</p>
<div>
{model.thinking.value
? <button>Adding...</button>
: <button onClick={actions.ADD_CLICKED_ASYNC}>Click me (async)</button>
}
</div>
<div>
<button onClick={actions.ADD_CLICKED}>Click me</button>
</div>
</div>
)
}
ReactDOM.render(
<Example />,
document.getElementById('hello-example')
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment