Global State — Series 2

Preview — 3 of 10 questions

Both snippets look like they're mutating an array the same way. Are they equally safe?

javascript
// Inside a Redux Toolkit slice (uses Immer internally):
const slice = createSlice({
  name: 'cart',
  initialState: { items: [] },
  reducers: {
    addItem: (state, action) => {
      state.items.push(action.payload); // looks like mutation
    },
  },
});

// Meanwhile, in a plain React component:
function LocalCart() {
  const [items, setItems] = useState([]);
  function addItem(item) {
    items.push(item); // looks identical — is it equally safe?
  }
}
AYes — both are completely safe, since JavaScript arrays are mutable objects in both cases and React handles mutation transparently either way
BNo — the useState version is actually the safe one; the Immer version inside createSlice is the one that silently breaks
CNo — the Immer-powered createSlice reducer is specifically safe only because Redux Toolkit wraps every reducer body in Immer's produce, which intercepts what looks like direct mutation and, behind the scenes, actually builds a new, properly immutable state tree; the plain useState version has no such interception — items.push(item) genuinely, unsafely mutates the existing array in place, and calling setItems(items) (or simply not calling any setter, as shown) would fail to trigger a correct re-render, exactly like the earlier useState mutation examples
DBoth are unsafe — Immer only works with objects, never arrays, so the createSlice example is equally broken

In Redux Toolkit's default development configuration, what actually happens when cart.items.push(item) runs here — code that mutates Redux state directly, from outside any reducer?

javascript
// In a component, accidentally mutating Redux state directly (a bug):
function BuggyComponent() {
  const cart = useSelector(state => state.cart);
  function addItemWrong(item) {
    cart.items.push(item); // mutating Redux state OUTSIDE a reducer — a bug
    dispatch(someUnrelatedAction());
  }
}
ANothing happens — Redux Toolkit doesn't validate mutation at all, in development or production; this bug would go completely undetected
BThe mutation succeeds silently, and every component reading state.cart immediately reflects the pushed item, functioning correctly by accident
CThis throws a TypeScript compile-time error, so the code could never actually run in the first place
DIn development, Redux Toolkit includes a middleware that deep-freezes the state tree and actively checks for mutations between dispatches — this specific mutation would be caught and throw a clear error immediately, pointing at the illegal mutation, rather than silently corrupting state or failing mysteriously later

If author 7's name needs to be updated (e.g., after they change their display name), what concrete bug does the nested shape risk that the normalized shape avoids?

javascript
// Nested/duplicated shape:
const state = {
  posts: [
    { id: 1, title: 'Hello', author: { id: 7, name: 'Alex' } },
    { id: 2, title: 'World', author: { id: 7, name: 'Alex' } }, // same author, duplicated
  ],
};

// Normalized shape:
const normalizedState = {
  posts: { byId: { 1: { id: 1, title: 'Hello', authorId: 7 }, 2: { id: 2, title: 'World', authorId: 7 } }, allIds: [1, 2] },
  authors: { byId: { 7: { id: 7, name: 'Alex' } }, allIds: [7] },
};
AThe nested shape risks updating the author's name in one post's embedded copy but forgetting to update it in every other post that embeds the same author, leaving inconsistent, duplicated data — different posts could end up showing different names for the same actual author; the normalized shape has exactly one copy of each author, updated in exactly one place, so every post referencing authorId: 7 automatically reflects the update
BThe nested shape is actually more efficient for this exact update, since only the specific post's author needs to change, not a whole separate authors table
CThere's no real difference — both shapes require the same amount of code to update an author's name correctly
DNormalized state is required by Redux — the nested shape shown would actually fail to work with useSelector at all

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.