React has released 16.8 version with Hooks as a new addition. Hooks are JavaScript functions that allow functional components to access state and life cycle methods. Since then, the focus of development has shifted towards functional components.

In the React-Redux ecosystem, Higher-Order Components are usually used to inject the additional data, functions, props or state. These components act as a wrapper — they take a component and return an enhanced one. In the case where the Higher-Order Component renders a single component, Hook API can be an alternative, eliminating the need for a wrapper. Using Higher-Order Components frequently and with, sometimes, multi-layer wrappers leads to a cumbersome and hard-to-maintain code. By using the Hook API, components are kept small and the code remains clean.

After the release of React hooks, Redux also released its version 7.1.0, supporting hooks for existing React-Redux API. The addition of hooks for React-Redux was much needed as it would increase the performance of the React application.

Life of Redux Application before Redux Hooks:

Any Redux application that uses the container component pattern connects its components to the Redux store using the Higher-Order Component, “connect()” function. The “connect()” is set using global state props and a dispatch method to make a change in the global state of any component.

const mapStateToProps = state => ({
  todos: getVisibleTodos(state.todos, state.visibilityFilter)
})
 
const mapDispatchToProps = dispatch => ({
  toggleTodo: id => dispatch(toggleTodo(id))
})
 
export default connect(
  mapStateToProps,
  mapDispatchToProps
)

example.js

Hooks for React-Redux:

Redux hook API can replace the higher-order component, “connect()”, with hooks like “useSelector” and “useDispatch”. Currently, React-Redux provides 3 hooks:

  1. useSelector(): useSelector hook is a replacement of the mapStateToProps. It runs whenever function component renders. Its purpose is to extract data from the Redux store state.
  2. useDispatch(): It acts as a replacement for mapDispatchToProps. It returns to the reference to the dispatch object.
  3. useStore(): This returns the reference of the Redux store that was wrapped in the provider. It is not recommended for frequent use but can be used in scenarios like replacing reducers.

A sample application will help you to understand these concepts better.

Sample Application using React-Redux Hooks:

In this article, we will create a small application using React-Redux Hook’s “useSelector” and “useDispatch” in a React application.

Installation:

Redux can be installed as a package from npm.

npm install --save redux

command.txt

Next, we will create a React application in the folder my-app, and we will use the npm package manager to create the React application. You can even use the npx package, which is available on npm@5.2.0 or later versions.

npx create-react-app my-appfolder

command.txt
If you don’t have npx, you can create a React app using npm.


npm init create-react-app my-app

command.txt

Folder Structure

The my-app folder will be created according to the structure given below. In this folder, you can initialize the project and install the transitive dependencies.

This is image title

Now, change the directory to “my-app”.

cd my-app

command.txt
Next, We will install React and Redux-React libraries.

npm i redux react-redux

command.txt
Now, you can open your “my-app” folder in your editor and create a new file called vehicle.js in your “src” folder.

import React from 'react';	
 
function reducer(state = {vehicle: ''}, action){
switch (action.type) {
    case "Car":
    return {
      vehicle: "It is a Car"
    };
    case "Bike":
    return {
      vehicle: "It is a Bike"
    };
    default:
      return "No";
  }
}
 
export default reducer;
 

vehicle.js

In the above code, we have a “reducer()” with two types of actions, “Car” and “Bike.”This function returns an appropriate value that is set for these actions.

Next, open your index.js File and add the code given below.

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";
import reducer from "./vehicle.js";
import App from "./app";
 
const vehicle = createStore(reducer);
 
const rootElement = document.getElementById("root");
 
ReactDOM.render(
  <Provider store={vehicle}>
    <App />
  </Provider>,
  rootElement
);

index.js

Now, that our Redux setup is complete, we will access the vehicles from the functional components using React hooks.

In the App.js file, we will now add the hooks useSelector and useDispatch.

The useSelector hook works similar to the connect’s mapStatetoprops. It enables us to access the entire Redux store state. Also, It subscribes to the Redux store state.

We need to import “useSelector” from the “React-Redux” library before using it. This useSelector() takes the state as an argument and returns the Redux store state.

import React from "react";
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux";
 
function App() {
  const counter = useSelector(state => state);
  const dispatch = useDispatch();
 
  return (
    <div className="App">
      
      <button
        onClick={() =>
          dispatch({
            type: "Car"
          })
        }
      >
    Car
    </button> &nbsp;&nbsp;&nbsp;
    <h1>{counter.vehicle}</h1>
    <button
        onClick={() =>
          dispatch({
            type: "Bike"
          })
        }
      >
    Bike
      </button>  
    </div>
   
  );
}
 
export default App;

App.js
useDispatch works similar to “mapDispatchToProps” as it is also used to dispatch the actions. Once we click on the buttons, the appropriate action is dispatched.

When you run this app in development mode, it will open http://localhost:3000 to view in the Browser.

Result:

You can see the result of the sample application below. Once you click on the button, you will see the result of the dispatched action.

This is image title

Refactoring Existing Application for Redux Hooks:

If you are about to use React-Redux hooks in an existing Redux application, you will have to consider the following modifications.

Relevant Components dispatching their Actions:

We can now let the components to dispatch their corresponding actions. For example, the MenuItemToggleComponent will dispatch the toggleItem action while the ButtonComponent will dispatch the saveItem and deleteItem actions.

Integrating Hooks

Replacing our “connect()” with hooks “useSelector()” and “useDispatch().” It is not necessary to connect all the components in the hierarchy to the store.

By integrating with hooks :

  1. It is easier to manage the states.
  2. It simplifies the code and makes it more readable.
  3. It extracts the stateful logic and makes it easier to share it.
  4. It reduces the extra components needed in the hierarchy.

Conclusion

React is popular for its ability to write functional components. With the React-Redux release, we can use the Hook API to manage the state without using the higher-order components. Thus, we no longer need to add extra components to the component tree. Next, our sample application showed the use of Redux Hooks, useSelector and useDispatch, to completely replace the use of the Higher-Order Component “connect().”

#reactjs #javascript #programming

Using Redux with React Hooks
15.05 GEEK