React State Model
React state holds information that changes over time and affects what a component displays or how it behaves. Keep the smallest necessary set of values in state, and calculate other values from that state during rendering to avoid duplicated data and synchronization problems.
React components use state to remember information between renders. When state changes, React can render the component again to reflect the updated information. Common examples include a selected tab, a counter, or the text entered into an input field.
A useful state model stores only information that must persist across renders and cannot be directly obtained from other available data. For example, a shopping cart might store its items in state rather than separately storing the number of items and the total price.
Values that can be calculated from props, state, or other existing data should generally be derived during rendering. If a component already has an array of products, it can calculate the number of products with `products.length` instead of maintaining another state variable for the count.
Duplicating derived information creates extra responsibilities. When the original data changes, every duplicate must be updated correctly. If one update is missed, the component can display inconsistent results. Deriving values directly avoids this synchronization burden.
React state is associated with a component's position in the rendered tree. Calling a state setter requests another render, but the current render continues to use its existing state snapshot. When a new value depends on the previous one, a functional update such as `setCount(previous => previous + 1)` helps ensure that the update uses the appropriate previous value.
Not every changing value belongs in state. Information that does not affect rendering, such as an interval identifier, may belong in a ref. Values that can be computed immediately from existing data usually do not need state at all.
Key points
- Store the minimum information necessary to represent a component's changing data.
- Calculate values that can be derived from props or state during rendering.
- Avoid storing duplicate representations of the same information.
- Use state setters to request updates rather than modifying state directly.
- Use functional state updates when the next value depends on the previous value.
- Use refs for mutable values that do not need to trigger a render.
Interview questions
Why should you avoid storing values that can be derived from other state?
A derived value can be calculated from information the component already has. Storing both the original data and a duplicate creates the possibility that they will disagree. Computing the derived value during rendering removes the need to synchronize two representations. This makes the component easier to maintain and reason about.
What is React state, and why do components need it?
State is information that a component retains between renders. It is useful for values that change over time and influence the component's output or behavior. When a state setter requests an update, React can render the component again using the updated state. Examples include a counter, a selected option, and form input values.
How would you implement a counter that increments correctly?
I would initialize the counter with `useState(0)` and update it using a state setter. When the next value depends on the previous value, I would use `setCount(previous => previous + 1)`. This form calculates the next state from the previous state supplied by React. It avoids relying on a potentially outdated value captured by the current render.
What is the difference between state and a ref?
State is designed for values that participate in rendering and must be updated through React's state mechanism. Updating state can schedule a re-render. A ref provides a mutable object whose `current` property persists across renders without triggering a render when changed. I would use state for visible values and a ref for information such as a timer identifier or a DOM reference.
How would you decide whether a value belongs in state?
I would first check whether the value can be calculated from existing props or state. If it can, I would usually derive it during rendering instead of creating another state variable. If it represents information that must persist across renders and changes independently, state may be appropriate. If it must persist but does not affect the rendered output, a ref may be a better fit.
How can duplicated state lead to bugs, and how would you refactor it?
Duplicated state can become inconsistent when related values are updated through separate code paths. For example, storing a product list and its count independently means every operation must keep both values aligned. I would identify the authoritative data and calculate the count from that source during rendering. If the calculation is expensive, I would consider memoization after evaluating whether the optimization is necessary.