Use option 1 when the new state is independent of the previous state, like fetching data from a server and you are simply replacing current state.
Use option 2 when the next state depends on the current state, like incrementing a count.
BTW, option 2's pattern is called a functional update since you pass it a pure function that takes the current state, mutates it, and returns the next state.
The following is a counting demo I've created to really show the difference between the two and why the distinction is important.
const [count, setCount] = useState(0); /** * count +3 click handler using naive state updates. */ const clickHandler1 = () => { // assume count equals some number n setCount(count + 1); // update queued, count === n, count = n + 1 setCount(count + 1); // update queued, count === n, count = n + 1 setCount(count + 1); // update queued, count === n, count = n + 1 // when processed the count will be n + 1 }; /** * count +3 click handler using functional state updates. */ const clickHandler2 = () => { // assume count equals some number n setCount(count => count + 1); // update queued, count === n + 0, count = prevCount + 1 setCount(count => count + 1); // update queued, count === n + 1, count = prevCount + 1 setCount(count => count + 1); // update queued, count === n + 2, count = prevCount + 1 // now when processed each call uses the result of the previous update // count will be n + 1 + 1 + 1, or n + 3 };

component.setState()method. But the OP's asking aboutuseState()returned function. Passing callback to the two meanings very different things..setState(cb1, cb2)method can accept two callbacks.cb1is the same concept. Before I always have the impression that its signature is.setState(partialState, cb).