Just a follow up. If foo and bar are expected to be constant in the rendering code, what's the point of the setXXX() functions? Why not just make them constant explicitly and say mutating them elsewhere like in the handlers/controllers?
React inverts the MVC paradigm and says "no, you don't get to decide when to render." So if you want to update state, React will manage that for you and queue up the render. With React, your UI and state literally cannot go out of sync (except for refs), and all the data dependencies are managed for you.
Facebook gave a great talk on Flux architecture vs MVC ten years ago that you should check out here: https://www.youtube.com/watch?v=nYkdrAPrdcw
> what's the point of the setXXX() functions? Why not just make them constant explicitly
Look at the code again: it is explicitly constant! `const [myState, setMyState] = useState(0)`. `myState` is a const, and will literally not change its value for the entire render cycle. There is no mutable state to manage, no race conditions. You just tell React what to render based on what the value is now, and React injects the current value for you. The first time, `myState` is 0 since that's the initial value. Every subsequent render, React will give you the latest value. You can pretend everything is constant, because it is.
First of all, I don't believe React component is pure functional with the state hooks embedded inside the component with side effects. Calling UI=F(props) twice with the same props would not produce the same result given the different sets of states embedded in them.
Second, the local variable myState is const but the state is mutable; the variable myState is an alias snapshot of the state. Otherwise what's the purpose of handing out setMyState? setMyState is for mutating the state, right? It seems the need to keep myState constant is due to React's inability to detect changes to the variable to sync up the UI. It uses setXXX() to trigger the UI re-rendering. However, whether setXXX() queuing up re-rendering and causing re-rending loop is inconsequential to the programmers. It's React's implementation detail.
Third, I'm interesting in learning what kind of bugs mutable state would cause in React, so that we can design better systems down the road.
Correct, but you as the component writer don't care. From your perspective, you are writing a purely functional component because you have no control over the injected state. So your function is "pure" with respect to the props that are passed in and the state that is injected by React. It's actually UI = F(props, state)
React can (and will) run your component function multiple times with different values before rendering, so it is extremely important that you have no actual side effects. Otherwise, these "intermediate renders" will affect the final render, which breaks the contract that your function return the same values for the same inputs.
> the local variable myState is const but the state is mutable
It is "mutable" in the sense that it changes between invocations of your function. But no, it is immutable within a single render of your function. The fact that you can treat all state as constant is one of the massive advantages of using React. You literally don't have to think about state mutating within a render cycle. You just write a function that spits out JSX given props and state.
> Third, I'm interesting in learning what kind of bugs mutable state would cause in React
You're going to run into issues where:
* the order that your function is called somehow affects the final render. Now you need to worry about how your function is called, and with what values. Not an issue with React.
* the underlying state is out of sync with the UI, because you changed it but didn't trigger a re-render. Not possible in React (except for refs).
* the internal state of the component ends up in an invalid state because of the ordering of set-state calls and renders. Again, not possible in React because all set-states are batched together and applied consistently to the next render cycle. There's no such thing as a "partial render".