Consistent React-Redux workflow

One-directional code writing to help starters understand redux


Split logic into domains.
Each domain contains action-types, actions, reducers, selectors and services.
write from : services => action-types => actions =>reducers =>selectors => containers => components.
Repeat this a few times and break away from it.

The Challenge

When my colleagues and I started writing code using React 4 months ago, i thought redux was part of react, since everyone was using it alongside react and so it would be straight forward. It became evident, however, that many developers have their own interpretations of how to handle redux. After going through millions of articles here on Medium and other great sources, I created an easy way to help starters like myself understand it.

This guide is not the Bible truth, and I encourage any criticism, positive or otherwise. Just read through and see how you can apply it to your project.

Redux Domains

I encourage splitting the redux store into domains that represent modules of your applications. It makes the code more modular and readable to other developers. 


The Workflow

There is a lot of back and forth between files when writing the logic of the applications. This workflow is meant to help the developer only write once in each file, in the order above without having to go back.

This does not mean that you should not go back and forth, it only makes it simple when getting started. My colleagues and I found that after using this workflow 4–5 times, we were much more comfortable working on any file without fear of the breaking the code. I encourage anyone who uses this to also do the same.


You can use any boilerplate of your choice. create-react-app is a good boilerplate to use. You can also use mine


This file will make the API calls to your server. For this example, I’ll fetch posts from this site.

class JsonPlaceHolderService{
    static getPosts(){
        const url = ''
        //define my request
        const request = {
            method: "GET",            
        //make the call and return a json object of the response
        return fetch(url, request)
            .then(response => {                
                return response.json()
            .catch(error => {
                throw( error)

export default JsonPlaceHolderService


In this file we define the nature that our actions. They describe what kind of actions we can dispatch.

export const POSTS_RECEIVED = 'posts.POSTS_RECEIVED'


Action creators are called from the user interface and dispatch actions of a certain type as listed above.

import * as types from "./actionTypes"
import JsonPlaceHolderService from "./service"

export function fetchPosts(){
    return function(dispatch, getState){
        //dispatch an action to show the starte
        dispatch({type: types.POSTS_REQUESTED})
        return JsonPlaceHolderService.getPosts()
            .then(posts =>{                
                    type: types.POSTS_RECEIVED,
                    payload : posts                    
            .catch(error =>{


The reducer will receive any action that is created and will switch based on the type of action defined in action types. In this case, it will add to an array of posts. 
I have used seamless immutable to make the state immutable.

import * as types from "./actionTypes"
import Immutable from "seamless-immutable"

const initialState = Immutable({
    posts: undefined,
    postsIsFetched: false

export default function postsReducer(state=initialState, action={}){
    switch (action.type) {
        case types.POSTS_RECEIVED:            
            return state.merge({
                posts: action.payload,
                postsIsFetched: true
            return state


Selectors provide data from the store( passed as state ) to the user interface( Container). In this case, the selector only returns the actual state value, but you can do manipulations to the objects before feeding it to the containers e.g. sorting, filtering e.t.c. Note that the values are accessed through the state.reducer.variable

export function getPosts(state){
    return state.postsReducer.posts

export function getPostStatus(state){
    return state.postsReducer.postsIsFetched


Containers are components that are connected to the redux store and access store variables through the state. they use mapStateToProps(), mapDispatchToProps(), bindActionCreators() and connect() functions. We will name our container PostScreen.
The variables from the state will be passed as props into container hence access using this.props.variable
The container and components are not stored in a domain folder because, there are not part of Redux and one container can be connected to multiple domains (e.g. user, posts )

import { connect } from 'react-redux'
import React, { Component } from "react"
import { bindActionCreators } from "redux"

//import actions and selectors from the Store folder
import * as postActions from "../Store/Posts/actions"
import * as postSelectors from "../Store/Posts/selectors"

//import your component
import PostItem from "../Components/PostItem"

class PostsPage extends Component {

    //when the component is mount, call the fetch post action

    //get alert from the  

                    this.props.postsIsFetched ?(
                            {, i) => (
                                <PostItem key={i} 

//get the posts and the fetch status from the post selector
const mapStateToProps = (state, ownProps) => {
    return {
        postsIsFetched: postSelectors.getPostStatus(state),
        posts: postSelectors.getPosts(state)

//mapp all actions in the post store to prop: postActions
const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        postActions: bindActionCreators(postActions, dispatch)

export default connect(mapStateToProps, mapDispatchToProps)(PostsPage)


The component is just a component that is not connected to the state (stateless components). It only receives its props from the container.

import React from 'react'

export const PostItem = (props) => {
                onClick={() =>{props.clickAction(}}>
                  view details 

export default PostItem

The bridge

We need to tie the store to the entire React app and we do this using the Provider component. This is not included in the workflow because it is only done once during the setup:

import { render } from "react-dom"
import React from "react"
import { Provider } from "react-redux"
import { combineReducers, createStore,  applyMiddleware  } from "redux"
import thunk from 'redux-thunk'

//import the post screen
import PostScreen from "Containers/PostScreen"

//import all your reducers from the store
import postsReducer from "./Store/Posts/reducers"

const rootReducer = combineReducers({

const store  = createStore(rootReducer, applyMiddleware(thunk))

    <Provider store={store}>


The final application can be found here
There is also a boilerplate built around this here

This article is heavily based on a great article by Tal Kol. Please check it out here
Another great article to look out for is this here


There no magic towards mastering redux. We can only try to stomach the fails as many times as is required to learn. I hope this helps you get a more consistent understanding of how flow moves in a redux application.

Good stuff? Consider sharing it!
Default image
Evans Munene
I pour milk before my cereal!