DEV Community

Cover image for Understanding Redux with React
bhupendra
bhupendra

Posted on

Understanding Redux with React

This is sequence of my earlier post about how to understand Redux in isolation and the problems it solves which cannot be solved by context API. To understand the importance of Redux in depth , here is an excellent article.

How to use React with Redux

Redux handles the store creation, middlewares & reducers logic. To use it with React, we need the instance of redux store for all components which is made available through Provider (using Context API). In Order to get the state and dispatch methods from the store we can use the connect from react-redux package. After Redux 7.0 we can use the useSelector and useDispatch hooks instead of wrapping our component with mapStateToProps and mapDispatchToProps.

Let's Build a React/Redux Project

We will continue building the project that was discussed in this post, but this time we will build the React UI also.

The project would have UI for two types of accounts: Current and Savings. There would also be a list of bank customers.
image

To get started we need to install below dependencies.
image

Here is how the directory structure of the project would look like:
image

In the previous , we have already seen how to setup action creators, reducers and combining reducers.
Here is how the redux store looks like now:

import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
import logger from "redux-logger";
import rootReducer from "./rootReducer";

const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(logger, thunk))
);

export default store;
Enter fullscreen mode Exit fullscreen mode

Store instance would be passed down the components tree via Provider

import { Provider } from "react-redux";
import store from "./redux/store";

export default function App() {
  return (
    <Provider store={store}>
      <div className="App">   
      ...    
      </div>
    </Provider>
  );
}
Enter fullscreen mode Exit fullscreen mode

To subscribe to the store we would be using useSelector hook and to get the dispatch function we would require useDispatch hook. Earlier connect function was difficult to setup with Typescript but now these hooks provide easy TS integration.

export default CurrentAccounts = () => {
  const amount = useSelector((state) => state.current.amount);
  const dispatch = useDispatch();

  return (
    <div>
      <label>Current Account</label>
      <h3>{amount}</h3>
      <div>
        <button onClick={() => dispatch(withdrawMoneyCurrent())}>
          Withdraw
        </button>
        <button onClick={() => dispatch(depositMoneyCurrent())}>Depoist</button>
      </div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Async Action Creator
We have used redux-thunk to call the dispatch function with actions in case of loading, success, error state for fetching data.

export const fetchCurrentUsers = () => {
  return function (dispatch) {
    dispatch(fetchStatusLoading);
    axios
      .get("https://jsonplaceholder.typicode.com/users")
      .then((res) => {
        const data = res.data.map((item) => ({ id: item.id, name: item.name }));
        dispatch(fetchStatusSuccess(data));
      })
      .catch((error) => {
        dispatch(fetchSatusError(error.message));
      });
  };
};

Enter fullscreen mode Exit fullscreen mode

👇 Here is the complete sandbox to practice above concepts

And if you have Redux Dev Tools chrome extension , then you can replay the state transitions , dispatch custom functions and generate tests.

image
If you are using redux only to fetch data and save it to a centralized store then there is an another way to do it with more efficient cache performance and less code ~ Redux Query. Dan's blog on when not to use Redux is also a worth to read.


Top comments (0)