const [username, setUsername] = useState('')
const onChange = event => setUsername(event.target.value)
const onSave = () => dispatch(saveUsername(username))
return (
<div>
<input value={username} onChange={onChange} />
<button onClick={onSave}>Save</button>
</div>
)
This code contains two closures2. Where are the closures and what's the necessity to use them?
2. onChange and onSave are both closures.
It isn’t technically necessary to use closures, but you need to find the correct setUsername from onChange, and since setUsername isn’t a global variable, closures are the natural and easy way to do it.
Hooks have shown that Super Serious programming can also be comedy, which is pretty cool.
I dunno, the functions-or-bust crowd happily doing and championing manual OO machinery fiddling amuses me.
[EDIT] what they couldn't have done, probably, would have been cleanly implementing that on top of class-based components without then having to tell their large and influential functions-are-the-only-way constituency that they'd need to write a lot more classes in the future. I suspect aversion to having to deliver that message is part of why we ended up with hooks as the solution, and classes left behind instead.
They were saying that for a long time before hooks when the only way they had it implemented at all was for classes, and functional components were usable for much narrower use cases. I suppose, if they could have done it cleanly with classes, they would have, whatever that meant saying to those downstream who aesthetically preferred functions. I don't know if it inherently worked better with functions, if the core devs themselves are just more proficient in that style, or if it was just a confluence of experience and the timing that the push to improve functional components occurred, but in the end functional components are just much cleaner.
1. https://overreacted.io/react-as-a-ui-runtime/
Where else would you propose putting UI rendering logic?
const todoItems = []
addTodoItem.addEventListener(event => {
todoItems.push(event.target.value)
renderTodoItems()
})