Free tools Windows power users keep installed
One-click scans. No signup required.
Start with useState for ordinary component state. If components need to stay coordinated, move their shared state to the closest common parent. Use useReducer when related updates are easier to manage together, and use context when distant descendants need the same value. Reach for useSyncExternalStore only when the data is genuinely owned outside React.
The guiding principle is to keep one clear source of truth, as close as practical to the components that use it. Calculate values that can be derived instead of storing duplicates, and use Effects to connect with external systems—not to keep React state synchronized with itself.
Choose a state location that matches its scope
State is information that can change over time and affect what the UI renders. The right place for it depends on which components use it, how they update it, and whether React or something else owns the data.
| Approach | Best fit | How updates work | Source of truth |
|---|---|---|---|
useState |
One component’s local UI state | A setter requests the next state value. | React component state. |
useReducer |
One component or screen with related transitions | Actions are handled by a reducer that returns the next state. | React component state. |
| Lift state to a common parent | Components such as siblings that must stay coordinated | The parent owns the state and passes values and handlers to children. | The common parent. |
| Context | Distant descendants that need a shared value | A provider supplies a value; consumers read it from the nearest provider above them. | The component that supplies the context value. |
useSyncExternalStore |
Data held outside React, such as a third-party store or browser API | The component subscribes and reads a snapshot. | The external store or API. |
React’s guidance is to prefer built-in useState and useReducer when they are enough. A broader state-management library is not the default starting point. See React’s guide to managing state for the principles behind choosing and structuring state.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
Use useState for straightforward local state
useState returns the current value and a setter. Calling the setter requests an update; it does not change the state value in code that is already running. The updated value is available on a subsequent render. The React useState reference documents the Hook’s behavior and setter forms.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
function increment() {
setCount(currentCount => currentCount + 1);
}
return (
<button onClick={increment}>Count: {count}</button>
);
}
Use the functional updater form, as above, when the next value depends on the previous one. It makes the dependency explicit rather than relying on a value captured earlier in the handler.
Keep state minimal and updates immutable
- Use separate state variables for independent facts when that makes their updates easier to understand. Group values when they naturally change together.
- For objects and arrays, produce a new value rather than mutating the existing state in place.
- Do not store a value that can be calculated from props or other state. For example, calculate a filtered list during rendering from the source list and current filter instead of storing both the source and filtered lists and synchronizing them.
Duplicate state can drift out of sync. If a value is merely a calculation from current inputs, derive it where it is needed rather than adding an Effect to update a second copy.
Lift state when components need to coordinate
If two components must display or change the same information, give them one source of truth. Move the state to their closest common parent, then pass the value and the necessary event handlers down as props. This is called lifting state up.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteFor example, if sibling components show a selected tab and its content, keeping separate selected-tab state in each sibling risks disagreement. The parent can own the selected tab and provide both children with the same value and a way to request a change. This is usually simpler than introducing context for a small, nearby component tree.
Use useReducer for related transitions
A reducer centralizes update logic. It receives the current state and an action, then returns the next state. This can help when several related transitions make event handlers difficult to follow—for example, a form whose fields, validation status, and submission state change through a set of defined events.
Rank #3
import { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'reset':
return { count: 0 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<>
<button onClick={() => dispatch({ type: 'increment' })}>
Count: {state.count}
</button>
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</>
);
}
Keep a reducer pure: its result should depend on its current state and action, without performing side effects. A reducer is not automatically preferable to useState; independent values with simple updates are often clearer with setters. React’s useReducer reference explains its API.
Use context to avoid forwarding shared values through every layer
Context lets a descendant read a value from the nearest matching provider above it, without each intermediate component forwarding that value as a prop. The context object describes the kind of value to read; the provider supplies the actual value. Components that read a context re-render when the provided value changes.
Context fits values genuinely shared across a subtree, particularly when passing props through many layers becomes inconvenient. It is not a requirement for every shared value or a universal replacement for local state. For components close together, props and lifted state can make data flow easier to see. See the useContext reference for provider and consumer behavior.
Rank #4
Combine reducer and context when both solve a real problem
For complex state shared by distant descendants, a reducer can own transitions while context makes the state and dispatch function available through the subtree. This combines centralized update logic with convenient access; it does not change the rule that state should live where it fits the UI and update needs.
Use useSyncExternalStore for data owned outside React
If a store or browser API owns the changing data, useSyncExternalStore provides a React subscription point. It takes a subscribe function and a getSnapshot function so React can be notified of changes and read the current snapshot. It is designed for external-store integrations, not as a more elaborate replacement for ordinary component state. When built-in state is sufficient, React recommends useState or useReducer instead. See the useSyncExternalStore reference for the subscription contract.
Keep Effects and performance Hooks in their proper roles
Effects are for synchronizing a component with an external system. React’s documentation puts the boundary plainly: “If you’re not interacting with an external system, you might not need an Effect.” — React documentation, “Built-in React Hooks”.
Recommended Free Tools
Best Value
Do not use an Effect merely to copy a prop or state value into another state variable when that value can be derived during rendering. That creates an additional synchronization path and can leave the UI inconsistent.
Other Hooks address distinct needs rather than providing another state store: useMemo caches a calculation, useCallback caches a function definition, and useTransition and useDeferredValue can help prioritize or defer non-blocking work. Use them when the corresponding calculation or responsiveness concern exists, not as a substitute for choosing the right owner and scope for state.
Understand when React preserves or resets state
React associates state with a component’s identity and position in the rendered tree. When the same component remains in the same position, React generally preserves its state. Changing a component’s key can intentionally give it a new identity and reset that state. This is useful when a form or draft should start fresh after switching to a different entity, such as changing the selected chat recipient.
Choose this deliberately: resetting by key discards the prior component state rather than merely recalculating a displayed value. React explains the behavior in Preserving and Resetting State.
Follow the Rules of Hooks
Call Hooks only at the top level of a function component or custom Hook, before any early return. Do not call them inside conditions, loops, nested functions, or try/catch blocks. React relies on a consistent Hook call order to associate state with the right component render. The Rules of Hooks reference gives the full requirements.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




