Redux is a tool that helps us manage and update states. It places all of the data (state) in one place which means that every component has access to the state regardless of where the component is located in its inheritance (parent, child or grandchild). A State is read only, meaning it cannot be altered.
An Action describes an event that occurred when the user clicked on something within the browser. Action is an object that contains the instructions and information that describes the state change. An Action contains two key and value pairs, Type and Payload. Type is a string that describes an action in a descriptive way and Payload is a data needed to complete the state change.
Reducer functions are used to update the state in response to actions. It is like an event listener which handles the events based on the received event (action) type. It receives a current state and an action object which describes how to update the state and returns the new state. It does not update the previous state, but creates a new state object.
Reducers always follow these rules:
- Only calculate the new state value based on the state and action arguments
- Does not modify the existing state. It copies the existing state and makes changes to the copied values
- Reducer is a pure function and it returns a value given a specific input and has no side effects. Reducer can be separated into smaller functions, but it becomes predictable
The logic inside a reducer function which uses if/else or switch statements:
- Does the reducer care about this action?
- If so, make a copy of the state, and update it with the new values and return it
- If not, return the existing state
State is stored within a single store object and should not directly change the state that is kept inside store. The store is created by passing in a reducer and has a method called getState() that returns the current state value.
Store has a method called dispatch. To update the state, it needs to call store.dispatch() and pass in an action object. The store will run its reducer function and save the new state value inside, and we can call
getState() to retrieve the updated value. It’s like triggering an event. Something happens and store needs to know. So, Reducers act like event listeners, and when an action is heard, it updates the state in response.
A data flow of initial setup:
- A store is created by root reducer function
- A value of an initial state is set by the return value of the root reducer which was called by the store
- The components access the current state of the store, and use that data to render the browser
A data flow of updating a state:
- When something happens on the browser, it dispatches an action to the store using the dispatch method
- The store runs the reducer function with the previous state and the current action. Then it saves the return value as the new state
- The store alerts the updates to all the components that are subscribed and each component checks the store if any pieces of the state got changed