Pure and Synchronous Disclaimer : This article is not an introduction to redux . There are a number of good resources to get started with redux (see below ) and I suggest you begin with them. This article isn’t about react either. The term “lifecycle” is used in context of redux data flow and operations. In just three years, redux has become quite a popular choice among frontend developers as the state management library of choice. Even more so in the react ecosystem. It’s amazing (and impressive, really) how small and simple the codebase is. And yet it can handle highly complex situations with easily. Perhaps this simplicity of redux is a major driving factor for its widespread popularity. In the , we’ll explore how middleware affect the redux lifecycle and the data flow. next part The Basic Redux Lifecycle Internally, redux only works with synchronous data flow and doesn’t come with many “moving parts” or magic methods like some other solutions. The most basic redux setup can be thought of as a single loop of state updates that is made up of just 2 components: The state tree The reducer function Actions are accessory objects that are required to figure out how to update the state for the next iteration. The reducer function takes in the previous state and the dispatched action as its arguments and returns the next state. If there are no changes needed, it returns the previous state . Otherwise, it creates new state and returns it. as-is Reducer Decomposition It is a common practice to split our state tree into multiple slices and write a separate reducer for each state slice. Actions may or may not be concerned with multiple state slices. This process of breaking our reducers into smaller and easier to understand pieces in a process called . Decomposition Independent Reducer Lifecycles Combining Reducers We can now combine several independent reducers back into a single reducer (often called the “root” reducer) and using it. create a redux store import { combineReducers } from 'redux' import from './foo'import from './bar'const = combineReducers({foo: fooReducer,bar: barReducer,}) fooReducer barReducer rootReducer Alternatively, we could exclude the ‘Reducer’ suffix from our imports to make the code . lighter import from './foo'import from './bar'const = combineReducers({foo,bar,}) foo bar rootReducer Basic Redux Lifecycle When an action is dispatched, the root reducer receives it and passes the same action object to all reducers for them to react to it independently. However, instead of passing the entire state tree to each reducer, redux will only pass the reducer’s state slice. The return value from each reducer is then merged back into the complete state tree. exclusive This is the basic redux and it is the most common one as well. With careful planning and division of the the app state most small-scale apps can work with this architecture without any added complexities. architecture smart State Dependent Reducers As your state tree grows complex, you may find yourself in situations where you need to share state between different reducers. A quick fix is to combine those reducers into one. However, doing so usually creates fat reducers that don’t scale well. If we want keep our reducers separate, we need to figure out whether we need to share the current state slice or the updated version. State Dependent Reducers — Current State Since reducers are just functions, we can pass them any number of arguments as we want. If a reducer requires state slice from another reducer, we can pass it in as the third argument. Current-State Dependent Reducers Combining Reducers We cannot combine dependent reducers using the utility that ships with redux. combineReducers() Once you go past the core use case for , it’s time to use more “custom” reducer logic — combineReducers Redux docs Since reducers are just functions, we can pass in the state of a different reducer as a third argument. import from './foo'import from './bar'function (state, action) {const = foo(state, action)const = bar(state, action, ) foo bar rootReducer fooState barState state.foo return {foo: fooState,bar: barState,}} Combining Current-State Dependent Reducers State Dependent Reducers — Updated State Generally, when a reducer depends on another reducer’s state, it requires the updated state. Personally, I have never come across a situation where the old state is required. If you know of any such experiences, do share them in the comments. Updated-State Dependent Reducers Combining Reducers The code looks almost the same as it was in the previous section. We have made only a small change. Instead of passing the old state in , we are now passing the updated state in . state.foo fooState import from './foo'import from './bar'function (state, action) {const = foo(state, action)const = bar(state, action, ) foo bar rootReducer fooState barState foo_State_ return {foo: fooState,bar: barState,}} Combining Updated-State Dependent Reducers Dependence on updated state of other reducers means that there is a vertical hierarchy of reducer invocation. This doesn’t mean much for trivial cases but the idea does hint the possibility of chaining reducers together. However, reducer chaining will increase the code complexity exponentially. Note : Another alternative to the “shared-slice updates” issue would be to simply put more data into the action. You can read more about it here . Putting it all together Now that we’ve seen some patterns of laying out reducers and combining them in isolation, let’s see what they look like in union. Here’s a list of key things to observe: Each reducer receives its exclusive slice of state as the first argument Each reducer receives the same action object as the second argument Dependent reducers receive the complete state or other reducers’ state slice as subsequent arguments All updated state slices are merged together into a single state tree Dependent reducers can form an invocation chain Redux uses reducers to perform state manipulations Complete Redux Lifecycle Addendum The missing bits In all of the drawings, I intentionally left out action creator(s) and the store to keep them clean and free from bloat. As you know: An action creator is a plain function that create an action object. The dispatch function accepts the action object and passes it to it’s store’s root reducer. The store is the place where the combined state tree and the dispatch function live. Each redux store has its own associated root reducer that consumes the action object and updates the store’s internal state. Resources for starting out Beginner’s guide to react/redux Getting Started with Redux Redux Basics Building React Applications with Idiomatic Redux The Complete Redux Book