DEV Community

Renato Rocha
Renato Rocha

Posted on

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

and the react-redux type definitions

yarn add @types/react-redux -D

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;

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 }
  };
}

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;
  }
}
/* 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;

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);

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
  })
);

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

Top comments (5)

Collapse
 
markerikson profile image
Mark Erikson

Hi, I'm a Redux maintainer. I'd specifically encourage you to try using our new official Redux Toolkit package, which includes utilities to simplify several common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once.

As part of that, the Redux Toolkit "Advanced Tutorial" docs page shows how to use RTK with TypeScript together with our new React-Redux hooks API.

Collapse
 
renatobentorocha profile image
Renato Rocha

Hi Mark, thanks a lot by the tip. I going to read about...

Collapse
 
kshitijbisht profile image
Kshitij Bisht

Hi,
I tried running your code in local. It doesnt work for me :(.
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
at validateString (internal/validators.js:120:11)

Collapse
 
renatobentorocha profile image
Renato Rocha

Hi Kshitij Bisht, thanks by comment.

I didn't be able to reproduce this error.

I did:

git clone https://github.com/renatobentorocha/react-redux-typescript.git
cd react-redux-typescript
yarn
yarn start

and worked fine.

Collapse
 
raupie profile image
Travis Raup

Yup, same error here.