Monday, January 1, 2024

How to create a React application using Redux hooks? Example Tutorial

Hello guys, Redux is one of the most popular state management library. It is often used with React apps that are huge in size and state are shared among multiple components. Redux is a complex library to understand and even more complex to implement. It was even more complex and complicated before the introduction of react-redux hooks. Earlier, the connect method provided by Redux was used to connect React with the Redux store. Using connect method with other methods such as mapstatetoprops was complicated. But with the introduction of react-redux hooks, it is easy to use redux with redux. In this article, we will discuss what are react-redux hooks and how to use them with React.



What is React redux Hooks? What are main Hooks?

React Redux Hooks refer to a set of hooks provided by the React Redux library, which is used for managing the state in a React application. React Redux is a library that helps in managing the state of a React application in a more predictable way, especially when dealing with larger and more complex applications.

React Redux provides traditional connect() function to connect your components to the store. However, with the introduction of React Hooks, React Redux also provides a set of hooks that allow you to interact with the Redux store directly from functional components, without the need for class components or the connect() function.

Here are some of the main React Redux Hooks:

1. useSelector()

This hook allows functional components to extract data from the Redux store. It takes a selector function as an argument, which specifies which part of the Redux store to subscribe to, and returns the selected data.

import { useSelector } from 'react-redux';

const MyComponent = () => {
  const data = useSelector(state => state.someReducer.someData);
  // ...
};


2. useDispatch()

This hook returns a reference to the dispatch function of the Redux store. You can use it to dispatch actions directly from your functional components.

import { useDispatch } from 'react-redux';

const MyComponent = () => {
  const dispatch = useDispatch();

  const handleClick = () => {
    dispatch(someAction());
  };

  // ...
};

3. useStore()

This hook returns the Redux store instance, allowing you to access the full store or perform other advanced interactions.

import { useStore } from 'react-redux';

const MyComponent = () => {
  const store = useStore();
  // ...
};

These hooks make it easier to integrate React components with the Redux store in a more concise and functional manner. Note that the specifics of libraries and their APIs may have evolved since my last update, so it's always a good idea to refer to the official documentation for the most accurate and up-to-date information.
 

In other world, there are two react-redux hooks - useDisptach and useSelector.


The useDispatch hook returns a reference to the dispatch method from the store. The reference is stored in a variable and then, actions are dispatched using it. 


The useSelector hook takes the current state as an argument and returns the global state or part of it. 


React Project Example - How to create a React application using Redux hooks?


Working with react-redux hooks

Now, let’s understand how to use both of these hooks with react with the help of an example. 


First install, redux, and react-redux using the following commands. 


npm install redux

npm install react-redux


First, we need to create a store. Create a new file in the “src“ folder and name it “store.js”. Add the following code to it.


import { createStore } from "redux";

const store = createStore()

 

export default store;


Next, open the “index.js” file and wrap the App component in the Provider. The store we created earlier must be provided as the value of the “store” attribute.


import React from "react";

import ReactDOM from "react-dom";

import { Provider } from "react-redux";

import App from "./App";

import reportWebVitals from "./reportWebVitals";

import store from "./store";

 

ReactDOM.rendr(

  <Provider store={store}>

    <App />

  </Provider>,

  document.getElementById("root")

);

 

reportWebVitals();


We will create three components and these three components will share the global state among them.


Component1:


import React from "react";

 

const Component1 = () => {

  const incrementHandler = () => {};

 

  const decrementHandler = () => {};

 

  return (

    <div>

      <button onClick={incrementHandler}>Increment</button>

      <button onClick={decrementHandler}>Decrement</button>

      <hr />

    </div>

  );

};

 

export default Component1;


Two buttons are defined in the “Component1” - one for incrementing value and the other for decrementing.


Component2:


import React from "react";

 

const Component2 = () => {

  return (

    <div>

      <h2>

    {}

</h2>

    </div>

  );

};

 

export default Component2;


“Component2” will display the state.


Component3:


import React from "react";

 

const Component3 = () => {

 

  const colorHandler = () => {

    let color;

    return color;

  };

 

  return (

    <div style={{ backgroundColor: colorHandler(), padding: "20px" }}></div>

  );

};

 

export default Component3;


In “Component3”, “count” will be used to determine the color of the div. 


We will create two actions - one to increment the value of “count” and the other to decrement it.


Create a new folder in “src” and name it “Actions”. In this folder, create a new file “actionCreators.js”. Add the following code to it. 


export const incrementAction = (count) => {

  return {

    type: "INCREMENT",

    payload: count,

  };

};

 

export const decrementAction = (count) => {

  return {

    type: "DECREMENT",

    payload: count,

  };

};



Next, create a new folder “Reducers” and add a new file “reducer.js” to it with the following code. 


export const reducer = (state = { count: 0 }, action) => {

  switch (action.type) {

    case "INCREMENT":

      return {

        ...state,

        count: action.payload + 1,

      };

    case "DECREMENT":

      return {

        ...state,

        count: action.payload - 1,

      };

    default:

      return { ...state };

  }

};


The reducer receives the state and action as parameters. Then, according to the “type” of action, the new state is returned. The “payload” is used to make changes in the “count”.


Let’s make some changes to the store. 


import { createStore } from "redux";

import { reducer } from "./Reducers/reducers";

 

const initialState = {

  count: 0,

};

 

const store = createStore(reducer, initialState);

 

export default store;


An initial state is added to the store. Now we can use react-redux hooks.


Let’s use the useSelector hook to fetch the global state in “Component2”.


import React from "react";

import { useSelector } from "react-redux";

 

const Component2 = () => {

  const { count } = useSelector((state) => state);

 

  return (

    <div>

      <h2>{count}</h2>

<hr />

    </div>

  );

};

 

export default Component2;


In the above component, “count” is extracted from the global state using the useSelector hook.


Similarly, we can use the useSelector hook to extract “count” from the global state in “Component3”


import React from "react";

import { useSelector } from "react-redux";

 

const Component3 = () => {

  const { count } = useSelector((state) => state);

 

  const colorHandler = () => {

    let color = count > 0 ? "green" : count < 0 ? "red" : "grey";

    return color;

  };

  return (

    <div style={{ backgroundColor: colorHandler(), padding: "20px" }}></div>

  );

};

 

export default Component3;


The “count” is used in the “colorHandler” to determine the color of the div. 


Now, let’s use the useSelector hook as well as the useDispatch hook in the “Component1”.


import React from "react";

import { useSelector, useDispatch } from "react-redux";

import {

  decrementAction,

  incrementAction,

} from "../ActionCreators/actionCreators";

 

const Component1 = () => {

  const dispatch = useDispatch();

  const { count } = useSelector((state) => state);

 

  const incrementHandler = () => {

    dispatch(incrementAction(count));

  };

 

  const decrementHandler = () => {

    dispatch(decrementAction(count));

  };

 

  return (

    <div>

      <button onClick={incrementHandler}>Increment</button>

      <button onClick={decrementHandler}>Decrement</button>

      <hr />

    </div>

  );

};

 

export default Component1;


In the “Component1”, first, the reference from the useDispatch hook is stored in a variable and then, the dispatch is used inside the “incrementHandler” and “decrementHandler” to dispatch the actions. We need the “count” because it should be passed to the actions creators and for this, we used the useSelector hook.

Everything is ready. Let’s check the output.
 



Yes, the value of “count” is changing on button clicks. Because of the change in the “count”, the color div is also changing.



Wrapping it up
Understanding react-redux hooks can take some time and practice but once you understand the concept of these hooks, working with redux will be very easy. In this tutorial, we discussed what are useDispatch and useSelector hooks and how to use them to manage the global state in redux.

Other React and Web development Articles and resources you may like


Thanks for reading this article so far.  If you like this React tutorial and examples of useEfect hooks, then please share them with your friends and colleagues. If you have any questions or feedback, then please drop a comment.


P. S. - If you are a beginner and want to learn React.js from scratch and looking for free React courses to learn concepts like components, virtual DOM, etc then I also recommend you to join these free online REact.js courses for beginners. It contains free courses from Udemy, Coursera, edX to learn to React online for FREE.        


1 comment:

  1. What are the pros and cons of using hooks in React.js?

    ReplyDelete