4 ms·
Not sure what you mean by invalid code. This is working code. import { useState } from 'react' function App() { const [count, setCount] = useState({ a
by mlnj 5y ago
Not sure what you mean by invalid code. This is working code.
import { useState } from 'react'
function App() {
const [count, setCount] = useState({ a: 0 })
return (
<button type="button" onClick={() => setCount({ ...count, a: count.a + 1 })}>
{count.a}
</button>
)
}
Cognitive load adds over time and I think it's so much simpler to break down such loads into smaller pieces that are documented well and abstract away the complexities/syntactic nuances. In short I keep forgetting to spread the previous state and that led to bugs for me.
Edit: Yes, you are right about the stale state and that was one of the primary reasons for me to not make it a pattern everywhere.
- andrewstuart 5y ago>> Not sure what you mean by invalid code. This is working code. It MIGHT work, but it is still incorrect code - you must always use an update function if you are updating state, it's not optional. Let's put it another way to be clear. This code is using stale state, don't use stale state: <button type="button" onClick={() => setCount({ ...count, a: count.a + 1 })}> The example you give above is incorrect code - it does not work the way you think - you need to update your understanding of React. React batches the useState calls and executes them later - so you must be very clear about the data you are using in the useState function - picking up the state value from the enclosing code gives you a state value that you cannot trust. The ONLY reliable to way actually get the previous state is to use a function as the argument to setState. In he example above, you think you are getting the current value of count, but it might be stale - this is critical to understand in React and if you don't understand it then you'll be fighting weird bugs forever. If you wish to use existing state, when you pass an update function to setState then React ensures that the previous state argument passed in is in fact the previous state. i.e: <button type="button" onClick={() => setCount({ ...count, a: count.a + 1 })}> should be: <button type="button" onClick={() => setCount(prevCount => ({ ...prevCount, a: prevCount.a + 1 }))}> I think that's the correct brackets but HN is not an IDE. The rule is simple: if you are updating state, ALWAYS pass an update function. The reason I have an issue with the topic of this HN post is that updating state is critically important in React and you should understand how it works and do it correctly, with a function call that uses previous state. useState with a function call is not boilerplate to be abstracted away, it's a simple and unambiguous way of writing React code and is central to writing React apps correctly - don't hide this.