DEV Community

Cover image for Structuring Redux in a React Web App
OlumideSamuel
OlumideSamuel

Posted on

Structuring Redux in a React Web App

What is Redux?

Redux is a state management tool used when building complex web applications using javascript frameworks. React-Redux is built specifically for react framework, it is maintained by the Redux team.

Why is React-Redux so important?

State management tool like React-Redux is necessary when building large or complex applications that require a consistent data structure that represents the state of your app that you can read from and write to. It makes passing data across components easily traceable.

Do you need it?

If you're building web portals or any data intensive web app, Yes, you'll need it to manage the data sent and received from the server per time.

What this article is and what not

It is NOT to explain fully what React-Redux is. To learn about react-redux, check this Link

It is to show how to set up and structure the react-redux for easy use. Basically, the boilerplate code you need to get started.

Let's Get Started

There are three major components of React-Redux

  • store
  • actions
  • reducers

Store - as the name implies, it's like a storehouse that house all our data. That is, where all our states are stored.

Actions - as the name implies, actions are the instructions the user issue to the redux to either write or fetch data from the store. They are objects with two major properties: {type: "DO_THIS", payload: dataObject}.

Reducers - reducers are functions that take actions from the application, perform an action and return a new state based on the action passed into it.

Install basic dependencies

npm i redux react-redux redux-thunk

  • create a store folder in your /src directory

In /src/store, add an index.js file to the store folder
In /src, add Actions folder
In /src, add Reducers folder

It should look something like:
store folder structure

  • In /src/actions/, action files are created according to modules so as to group similar concerns. For example, AuthenticationActions.js - may contain signInAction(); logoutAction(); BlogActions.js - may contain getBlogPostAction(); deleteCommentAction(); updateBlogPostAction(); etc..

For this example, we'll create a TestAction.js file that fetches users from https://jsonplaceholder.typicode.com/users

In /src/actions/TestAction.js,



export const getAllPosts = () => {
  return (dispatch) => {
    //   fetch placeholder data from jsonplaceholder
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((response) => response.json())
      .then((result) =>
        //dispatch response to the store
        dispatch({ type: "DO_THIS", payload: result })
      );
  };
};


Enter fullscreen mode Exit fullscreen mode

In /src/reducer/, create TestReducer.js file, several reducers can be created to handle the state for specific modules within our application.
Create a Test Reducer function that accepts two parameters,
- state (with the default set to its original state) and action
- Use switch to check action type and then update state.

In /src/reducer/TestReducer.js



const initialState = {
  users: null,
};

export default function TestReducer(state = initialState, action) {
  switch (action.type) {
    case "DO_THIS":
      return {
        ...state,
        users: action.payload,
      };
    default:
      return state;
  }
}


Enter fullscreen mode Exit fullscreen mode

In /src/reducer/, create an index.js file within Reducer folder to combine all reducers. Redux provides us with a combineReducer function for combining all reducers in the app.
- const reducer = combineReducer({});

In /src/reducer/TestReducer.js,



import { combineReducers } from "redux";
import TestReducer from "./TestReducer";

const reducers = combineReducers({
  Test: TestReducer,
  //other reducers come here...
});

export default reducers;



Enter fullscreen mode Exit fullscreen mode

In /src/store/index.js, create a store for all reducers created.



import { applyMiddleware, createStore } from "redux";
import thunk from "redux-thunk";
import reducers from "./Reducers";

//thunk middleware is used to intercept actions so as to make API call before dispatching result to reducer
const store = createStore(reducers, applyMiddleware(thunk));

export default store;


Enter fullscreen mode Exit fullscreen mode

Finally,
In Index.js, Provide the store to the application globally



import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import store from "./store";

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);



Enter fullscreen mode Exit fullscreen mode

The Store file structure should look like

store file structure

To bring it all together

In App.js,

  • import useDispatch hook, to dispatch action that'll get fetch users from a remote server
  • dispatch that action on component mount,

/src/App.js
Alt Text

In src/components/Users.js,

  • Access data in TestReducer using useSelector hook
  • Map through data to display list of users

Alt Text

Resulting View

View

--

Note: There are several ways to structure this, this is just a fairly simple way to get up and running quickly. I hope this help you get started quickly. :)

Top comments (1)

Collapse
 
akerele180 profile image
Akerele, Tosin James

Did you write two different functions in the TestReducer.js file cos it seems like you mentioned it twice on different occasions and different purpose