When to Avoid React State

React state is a powerful tool for managing dynamic data, but overusing it can lead to unnecessary re-renders, complex codebases, and performance bottlenecks. This article explores the specific scenarios where you should avoid using React state—such as managing derived data, tracking values that do not affect the UI, and handling form inputs redundantly—and offers cleaner, more efficient alternatives like refs, local variables, and URL parameters.

1. Derived Data

One of the most common mistakes in React development is storing data in state that can be computed from existing props or state. Doing so introduces redundant synchronization logic, often requiring useEffect hooks, which increases the risk of bugs.

Instead of syncing props to state, calculate the values on the fly during render. If the calculation is computationally expensive, wrap it in the useMemo hook. For example, instead of storing a filtered list in state, compute the filtered list directly from the original list and the active search query during the render phase.

2. Values That Do Not Affect the UI

React state exists to trigger a re-render when data changes so that the user interface updates. If you have a variable that needs to persist across renders but does not affect what is displayed on the screen, do not use state.

Updating state triggers a full component re-render, which degrades performance if the UI does not actually change. Instead, use the useRef hook. A ref persists its .current property across renders without triggering a re-render when updated. Common use cases for useRef include storing interval or timeout IDs, tracking DOM elements, or keeping a count of component mounts.

3. Uncontrolled Form Inputs

While controlled components (where input values are bound to React state) are standard, they are not always necessary. Storing every keystroke in state for a large form can cause noticeable lag, as the entire form re-renders on every character typed.

For simple forms where you only need to read the values upon submission, use uncontrolled components. By leveraging useRef or the native FormData API on submission, you can retrieve the input values directly from the DOM without managing state.

4. URL-Driven State

If a state variable represents something that affects the current view—such as search queries, active filters, page numbers, or open tabs—avoid keeping it in local React state.

Instead, store this data directly in the URL query parameters. This ensures that the page state is bookmarkable and shareable. Keeping this information in the URL eliminates the need to synchronize local state with the browser history, simplifies deep linking, and utilizes the router as the single source of truth.