Use react hooks with react-redux in typescript

Use react hooks with react-redux in typescript

|
253

It's been more than a year when React introduced hooks. Many popular libraries that used with ReactJS like React-Router, React-Redux, Material UI, etc. now support hooks and functional components. But today in this article, I will show you the new way of accessing store and dispatch in your functional component without using higher-order components, and compare how hooks reduced huge pile of boilerplate.


Related Article: Latest Features of Typescript 2020 release


1. What are hooks in ReactJS?

What are react hooks?

Photo by chuttersnap on Unsplash

If you're aware of what are hooks in react, you can skip to the next section. 

React hook is a new concept introduced in React 16.8, that enables programmers the power to separate the logic from the UI. We all know that states used only in react component, so what if there's a logic bind with that state, and you want to use it in multiple files? You forced to return a JSX, which makes it a functional component. Now, that was the motivation.

So now, you can write a functional component hook, you can do everything that you do in a functional component except you can return anything rather than just a JSX. Hooks name start with use like useEffect, useState etc. It is not a strict rule, but it considered a standard to identify hooks.

2. React redux hooks: Class vs Functional component comparison

(See the complete code on Code Sandbox

I'm writing a simple class component and a functional component that render the name of a user. First, we dispatch the name of the user, and next, we select the name from the store in the component to display it in the component.

import * as React from "react";
import { connect } from "react-redux";
import { TReduxStore, TDispatch } from "./types";
import { AxiosPromise } from "axios";
import { getUser } from "./action";

type IStateProps = Pick<TReduxStore, "user">;

interface IDispatchProps {
  getUser: (id: string) => AxiosPromise;
}

interface IProps extends IStateProps, IDispatchProps {}

class ShowUser extends React.Component<IProps> {
  componentDidMount() {
    this.props.getUser("1");
  }

  render() {
    const { user } = this.props;
    return !user ? "Loading..." : <div>User Name: {user.name}</div>;
  }
}

const mapStateToProps = (state: TReduxStore): IStateProps => ({
  user: state.user
});

const mapDispatchToProps = (dispatch: TDispatch): IDispatchProps => ({
  getUser: id => dispatch(getUser(id))
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(ShowUser);

Above is the traditional way of connecting your ReactJS component with the redux. You have to write that much code just to request and display the user name. Now let's see the same thing in the functional component.

import * as React from "react";
import { useSelector, useDispatch } from "react-redux";
import { TReduxStore, TDispatch } from "./types";
import { getUser } from "./action";

type IStateProps = Pick<TReduxStore, "user">;

const ShowUser: React.FC = props => {
  const dispatch = useDispatch<TDispatch>();

  const { user } = useSelector<TReduxStore, IStateProps>(state => ({
    user: state.user
  }));

  React.useEffect(() => {
    dispatch(getUser("1"));
  }, [dispatch]);

  return !user ? <div>"Loading..."</div> : <div>User Name: {user.name}</div>;
};

export default ShowUser;

As you can see, using hooks, reduced the number of lines to almost half. I'm considering you're using the class component, so I'm not explaining that snippet. So I'm just explaining the FunctionalComponent.tsx below.

3. How to use useDispatch and useSelector react-redux hooks in your functional component?

Let's see one by one how to use the useDispatch and the useSelector to dispatch and select the data from the redux store.

How to use useDispatch and useSelector in react redux typescript

Photo by Chris Scott on Unsplash

  • useDispatch

    useDispatch hook used to get the redux dispatch function in your functional component or hook. It takes a generic type of data dispatch, takes in its parameters. Usually, it is {type: string, payload?: any} but as I'm redux-thunk here, so its type is ThunkDispatch<TReduxStore, {}, TAction>; where TReduxStore is the type of the store and TAction is {type: string, payload?: any}.

  • useSelector

    As its name suggests, it gives you the functionality of selecting the data from your redux store. It takes one parameter, which is a callback, where it passes the whole redux state, and you return the data you want to select from it. So the callback function looks like below.

    function (state) {
        return ({
            user: state.user
        })
    }

    The same thing I have written is in the flat arrow function format in the functional component. It takes two types in its generic type. One is the type of your redux store, and the second is the type you want to select from the store. IN my codes, it is represented by TReduxStore and IStateProps respectively.



Comments

© 2020 Garbage Valuegarbage value logo