Basic Reducer Structure and State Shape
- It needs to look at the previous state and the dispatched action, and determine what kind of work needs to be done
- Assuming actual changes need to occur, it needs to create new objects and arrays with the updated data and return those
Notice that this simple function fulfills all the basic requirements. It returns a default value if none exists, initializing the store; it determines what sort of update needs to be done based on the type of the action, and returns new values; and it returns the previous state if no work needs to be done.
There are some simple tweaks that can be made to this reducer. First, repeated /else
statements quickly grow tiresome, so it's very common to use switch
statements instead. Second, we can use ES6's default parameter values to handle the initial "no existing data" case. With those changes, the reducer would look like:
Basic State Shape
Redux encourages you to think about your application in terms of the data you need to manage. The data at any given point in time is the "state" of your application, and the structure and organization of that state is typically referred to as its "shape". The shape of your state plays a major role in how you structure your reducer logic.
A Redux state usually has a plain Javascript object as the top of the state tree. (It is certainly possible to have another type of data instead, such as a single number, an array, or a specialized data structure, but most libraries assume that the top-level value is a plain object.) The most common way to organize data within that top-level object is to further divide data into sub-trees, where each top-level key represents some "domain" or "slice" of related data. For example, a basic Todo app's state might look like:
Most applications deal with multiple types of data, which can be broadly divided into three categories:
- Domain data: data that the application needs to show, use, or modify (such as "all of the Todos retrieved from the server")
- App state: data that is specific to the application's behavior (such as "Todo #5 is currently selected", or "there is a request in progress to fetch Todos")
There will rarely be a 1-to-1 correspondence between your UI tree and your state shape. The exception to that might be if you are explicitly tracking various aspects of UI data in your Redux store as well, but even then the shape of the UI data and the shape of the domain data would likely be different.