How would you structure a scalable store for interconnected domains?
Tests domain-driven state partitioning and cross-slice derived data. Strong answers use feature slices, normalized entities, and memoized selectors; keep computed state out of the store. Red flag: a monolithic state tree with component-level recomputation.
WHAT THIS TESTS: This tests whether you can apply domain-driven design principles to client-side state management. The interviewer wants to see if you understand how to prevent a global store from becoming a tightly coupled monolith where every state change ripples unpredictably through unrelated domains. They are looking for awareness of normalization, selector composition, and the boundary between state and computed derivations.
A GOOD ANSWER COVERS: First, partition the store into domain-scoped slices such as users, products, and orders rather than mixing them into a single flat structure. Second, normalize state shape so that each slice owns its entities by ID and cross-domain references are stored as foreign keys, not nested objects. Third, use memoized selectors to compute cross-slice derived data; the selector layer is where you join users to orders or compute totals, keeping the store itself serializable and minimal. Fourth, keep computed or aggregate state out of the store to avoid synchronization bugs and redundant writes. Fifth, enforce unidirectional data flow where feature slices expose only their own actions and selectors, and shared selectors live in a thin orchestration layer.
COMMON WRONG ANSWERS: A red flag is proposing a single monolithic state object with deeply nested domain data. Another is storing computed values like cart totals or filtered lists directly in state, which creates multiple sources of truth. Candidates who suggest that components should manually combine multiple observables or stores to build derived data are missing the selector abstraction and will trigger excessive re-renders. Similarly, normalizing everything but then denormalizing inside reducers or actions shows confusion about where derivation belongs.
LIKELY FOLLOW-UPS: The interviewer may ask how you would handle a transaction that spans multiple domains, such as placing an order that must reserve inventory and update user loyalty points. They might also probe performance: how memoization works, how selector arity affects cache invalidation, or how to avoid selector recalculation when only unrelated slices change. Another follow-up is how to lazy-load feature stores in a micro-frontend or module federation context.
ONE CONCRETE EXAMPLE: Suppose an order detail view needs the order, the product names, and the user profile. In a normalized store, the orders slice stores productIds and userId. A composed selector starts from the orders slice, then looks up products by ID from the products slice and the user from the users slice. The component receives a single denormalized view model from the selector without knowing the store structure. If the user edits their profile, only the users slice updates and the order selector for unrelated orders does not recompute because its input references remain stable.
Read the original → ngrx.io
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.