Actions & Reducers — Series 3

Preview — 3 of 10 questions

What does props<{ item: CartItem }>() add here?

javascript
export const addItem = createAction(
  '[Cart] Add Item',
  props<{ item: CartItem }>(),
);
Aprops<T>() declares the shape of extra data this action carries beyond its type string — here, an object with an item: CartItem field. It gives the action creator function a typed parameter (addItem({ item })) and makes that same shape available, correctly typed, wherever the action is later handled (a reducer's on(), an effect)
BIt sets a default value for item if none is provided when the action is created
Cprops is only used for actions dispatched from effects, never from components
DIt validates the item at runtime, throwing if it doesn't match CartItem's shape

What does typing the injected Store as Store<AppState> (instead of a bare Store) actually buy?

javascript
interface AppState {
  cart: CartState;
  user: UserState;
}

constructor(private store: Store<AppState>) {}
ANothing at runtime or compile time; Store<AppState> and a plain Store behave identically in every way
BIt changes how many reducers can be registered with the store
CIt's purely documentation — TypeScript doesn't use the generic parameter for anything
DSelectors and store.select(...) calls made through this typed store are checked against AppState's actual shape — TypeScript can catch a typo in a selector path or a mismatched selected type at compile time, rather than only discovering the problem at runtime when undefined shows up somewhere unexpected

What are the two things createReducer needs, structurally?

javascript
export const cartReducer = createReducer(
  initialCartState,
  on(addItem, (state, { item }) => ({ ...state, items: [...state.items, item] })),
  on(clearCart, (state) => ({ ...state, items: [] })),
);
AA list of every possible action type as strings, and a single catch-all handler function
BAn initialState value, and a switch statement matching on action.type
CAn initialState value (used the very first time the reducer runs, or whenever an unmatched action passes through), followed by any number of on(actionCreator, handlerFn) pairs — each pairing a specific action (or several, if the same handler applies to multiple) with a function computing the new state from the old state and that action's payload
DA class implementing a reduce() method, plus a decorator specifying which actions it handles

Sign up free to play

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