5 questions foundWhat is state management in a React app?
Beginner State management refers to how an app organizes and shares data that changes over time, such as the current logged in user, items in a shopping cart, or a form's values. Small apps often manage this using useState and Context directly, while larger apps sometimes reach for a dedicated state management library to keep things organized.
function App() {
const [cartItems, setCartItems] = useState([]);
function addToCart(item) {
setCartItems([...cartItems, item]);
}
return <ProductList onAddToCart={addToCart} />;
}
Real-world example A small online store manages its shopping cart entirely with useState at the top of the app, passing the cart data and update function down to whichever components need them.
Common follow-ups: At what point does an app typically need more than just useState for managing its data?;What is the difference between local state and global state?
Context API;State Management Libraries (Redux Zustand & Recoil)
What is the difference between local state and global state in a React app?
Intermediate Local state belongs to a single component and is not needed anywhere else, such as whether a specific dropdown is open. Global state is data that many different, often unrelated components across the app need to read or update, such as the currently logged in user or the shopping cart contents.
// Local state, only this component cares about it
function Dropdown() {
const [isOpen, setIsOpen] = useState(false);
}
// Global state, needed by many different components across the app
const CartContext = React.createContext();
Real-world example A dropdown menu's open or closed status stays as simple local state inside that one component, while the shopping cart contents are lifted into global state so the header, the cart page, and the checkout page can all access the same data.
Common follow-ups: How do you decide whether a specific piece of data should be local or global?;What problems happen if too much state is unnecessarily made global?
Context API;Props & State
How do you decide between using Context, a state management library, or simply lifting state up?
Advanced Lifting state up works well when only a few closely related components need to share data. Context works well for moderately shared data that does not change extremely often, like a theme or the current user. A dedicated state management library becomes useful when an app has a lot of shared, frequently changing data, or when performance concerns make Context's re render behavior a real problem.
// Simple case, lifting state up is enough
function Parent() {
const [value, setValue] = useState('');
return <><Input value={value} onChange={setValue} /><Display value={value} /></>;
}
// Complex, frequently changing global data, a library like Zustand may fit better
Real-world example A small team app manages a shared color theme using Context, since it rarely changes, but switches to Zustand for their frequently updating real time notification data, since Context's re render behavior started causing performance issues there.
Common follow-ups: What specific performance problem can happen when Context is used for very frequently changing data?;How would you migrate from using Context to a dedicated state management library later if needed?
Context API;State Management Libraries (Redux Zustand & Recoil)
What does it mean for state to be normalized, and why does this matter for larger apps?
Intermediate Normalized state stores related data, like users and their posts, as separate flat collections referenced by id, instead of deeply nesting one inside the other. This avoids duplicating the same data in multiple places and makes updating a single piece of information, like a user's name, much simpler and less error prone.
// Not normalized, user data is duplicated inside every post
const posts = [{ id: 1, author: { id: 5, name: 'Alice' } }, { id: 2, author: { id: 5, name: 'Alice' } }];
// Normalized, user data lives in one place, referenced by id
const users = { 5: { name: 'Alice' } };
const posts = [{ id: 1, authorId: 5 }, { id: 2, authorId: 5 }];
Real-world example A social media app switches from storing full user objects inside every single post to storing just a user id, avoiding the bug where updating a user's display name previously required updating dozens of duplicated copies across many posts.
Common follow-ups: How do you look up a user's full details from a normalized posts list?;What tools or libraries help manage normalized state more easily?
State Management Libraries (Redux Zustand & Recoil);Design Patterns in React
What is a common sign that an app's state management approach needs to be reconsidered?
Beginner If the same piece of data needs to be passed through many layers of components that do not actually use it themselves, often called prop drilling, or if unrelated parts of an app frequently get out of sync with each other, these are common signs that it might be time to introduce Context or a dedicated state management library.
// A sign of trouble, passing a value through several components that never use it directly
<Layout user={user}>
<Sidebar user={user}>
<Profile user={user} /> {/* only this component actually needs the user */}
</Sidebar>
</Layout>
Real-world example A team notices they are passing a user object through four unrelated components just to reach one deeply nested component that actually needs it, and decides this is a clear sign to introduce Context instead.
Common follow-ups: What other early warning signs suggest state management needs improvement?;Is prop drilling always a bad thing, even in smaller apps?
Context API;Component Composition & Children Props