React Redux with TypeScript

renatobentorocha

Renato Rocha

Posted on January 28, 2020

React Redux with TypeScript

When we are writing a React Application and using React Redux to manage the application state we use a plain JavaScript. So its implies some difficulties, like: (i) code complete not available, that is, we do not have a suggestion about de code, parameters, properties and etc; (ii) static type checking is not working, making it impossible fast error detection and so on.

Install of dependencies

Thus the first step is configuring a React Project whit TypeScript. Now, we need install the React Redux dependencies:

yarn add redux react-redux
Enter fullscreen mode Exit fullscreen mode

and the react-redux type definitions

yarn add @types/react-redux -D
Enter fullscreen mode Exit fullscreen mode

State Types

To have the benefits of static type checking we need creating the types that will be used for state and actions creators.

Types definitions

/*  types.ts */

export interface Todo {
  id: number;
  description: string;
  checked: boolean;
}

export interface TodoState {
  data: Todo[];
}

export const CREATE_TODO_REQUEST = "@todo/CREATE_TODO_REQUEST";

interface CreateTodoRequest {
  type: typeof CREATE_TODO_REQUEST;
  payload: { todo: Todo };
}

export type TodoActionsTypes = CreateTodoRequest;
Enter fullscreen mode Exit fullscreen mode

Now that we have a interface defining how must be the format of our action, we can create it.

/* actions.ts */
import { TodoActionsTypes, Todo, CREATE_TODO_REQUEST } from "./types";

export function createTodo(todo: Todo): TodoActionsTypes {
  return {
    type: CREATE_TODO_REQUEST,
    payload: { todo }
  };
}
Enter fullscreen mode Exit fullscreen mode

In next step we will creating a Reducer to manage the state and export the combineReducers together with the RootState type.

/* reducer.ts */

import { TodoState, TodoActionsTypes, CREATE_TODO_REQUEST } from "./types";

const initialState: TodoState = {
  data: []
};

export default function todoReducer(
  state = initialState,
  action: TodoActionsTypes
): TodoState {
  switch (action.type) {
    case CREATE_TODO_REQUEST:
      return {
        data: [...state.data, action.payload.todo]
      };

    default:
      return state;
  }
}
Enter fullscreen mode Exit fullscreen mode
/* combineReducers.ts */

import { combineReducers } from "redux";
import todoReducer from "./todo_list/reducer";

const rootReducer = combineReducers({
  todo: todoReducer
});

export type RootState = ReturnType<typeof rootReducer>;
export default rootReducer;
Enter fullscreen mode Exit fullscreen mode

Access the state and dispatch action in a view

To access the state we can use the useSelector hook passing to it the RootState type so that we can saw our state structure

import { useSelector } from "react-redux";
import { RootState } from "../../store/modules/combineReducers";

const data = useSelector((state: RootState) => state.todo.data);
Enter fullscreen mode Exit fullscreen mode

useSelector

and using the useDispatch hook to fire our action.

import { useDispatch } from "react-redux";

import { createTodo } from "../../store/modules/todo_list/actions";

const dispatch = useDispatch();

dispatch(
  createTodo({
    id: lastId(),
    description,
    checked: false
  })
);
Enter fullscreen mode Exit fullscreen mode

useDispatch

In this quick post, using some code snippets, we saw a way to improve our code using TypeScript to static typing verifying of state on React Redux.

source code

💖 💪 🙅 🚩
renatobentorocha
Renato Rocha

Posted on January 28, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related