React Redux with TypeScript
Tags: react, redux, typescript
Published: 2020-01-28 17:46:44

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](https://dev.to/renatobentorocha/how-to-setup-a-react-js-project-with-typcript-eslint-and-prettier-8mn). Now, we need install the React Redux dependencies:

```shell
yarn add redux react-redux
```

and the react-redux type definitions

```shell
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

```typescript
/*  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.

```typescript
/* 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.

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

```typescript
/* 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

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

const data = useSelector((state: RootState) => state.todo.data);
```

![useSelector](https://raw.githubusercontent.com/renatobentorocha/react-redux-typescript/master/RootState.png)

and using the useDispatch hook to fire our action.

```typescript
import { useDispatch } from "react-redux";

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

const dispatch = useDispatch();

dispatch(
  createTodo({
    id: lastId(),
    description,
    checked: false
  })
);
```

![useDispatch](https://raw.githubusercontent.com/renatobentorocha/react-redux-typescript/master/useDispatch.png)

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](https://github.com/renatobentorocha/react-redux-typescript)