How to Setup your React app with Redux Toolkit and Typescript
Tags: react, redux, typescript, hooks
Published: 2020-09-26 15:31:20

**React** – a JavaScript library for building user interfaces --> [reactjs](https://reactjs.org/)

**Typescript** – is an open-source language that extends JavaScript by adding types. --> [typescript](https://www.typescriptlang.org/)

**Redux** is a predictable state container for JavaScript apps. It helps you write applications that behave consistently, run in different environments (client, server and native). --> [redux](https://redux.js.org/)

**Redux Toolkit** – as per official Redux documentation, it is recommended approach for writing Redux logic. It wraps around the Redux core, and contains all needed packages and functions for start building a Redux app. --> [redux-toolkit](https://redux-toolkit.js.org/)

**Why do we want to write single page apps?** - The main reason is that they allow us to offer a *more-native-app-like* experience to the user.

Developing modern web applications involves not only *UI building*, but also require state management. One of the most comprehensive library for this is **Redux**. In this tutorial you will learn how to setup **Redux** using the latest libraries and simplified techniques available in 2020.

### Table of Contents

- Why to choose Redux Toolkit
- How to Setup Create-React-App with Typescript and Redux
- How to Structure your Redux
- Connecting Redux with React using useDispatch and useSelector hooks
- Summary

---

**Why to choose Redux Toolkit**

- *Simple* – Includes utilities to simplify common use cases like store setup, creating reducers, immutable update logic, and more.

- *Opinionated* – Provides good defaults for store setup out of the box, and includes the most commonly used Redux addons build-in.

- *Powerful* – Takes inspiration from libraries like Immer and Autodux to let you write ‘mutative’ immutable update logic, and even create entire ‘slices’ of state automatically.

- *Effective* – Lets you focus on the core logic your app needs, so you can do more work with less code.

---

**How to Setup Create-React-App with Typescript and Redux**

For this *Redux toolkit tutorial* lets start with setup a new react application using *CRA*:

`npx create-react-app redux-toolkit –template typescript`

 or

`yarn create-react-app redux-toolkit –template typescript`

`npx on the first line is no a typo – it’s a package runner tool that comes with npm 5.2+`

**Note:**  
**If you’ve previously installed creat-react-app via npm globally, please uninstall the package using "npm uninstall name_of_the_package" to ensure that npx always uses the latest version. Global installs of create-react-app are no longer supported.**

`cd redux-toolkit`

`npm start` or `yarn start` (in case you are using ‘yarn’)

**Please double check if following packages are installed. In case they are not present, to add typescript to a create-react-app project, first install it:**

`npm install –save typescript @types/node @types/react @types/react-dom @types/jest`

or 

`yarn add typescript @types/node @types/react @types/react-dom @types/jest`

Next we will add [redux-toolkit](https://redux-toolkit.js.org/), [redux-logger](https://github.com/LogRocket/redux-logger#readme) and [uuid](https://github.com/uuidjs/uuid#readme) with following:

`npm install –save react-redux redux-logger @reduxjs/toolkit uuid`

  or

`yarn add react-redux redux-logger @reduxjs/toolkit  uuid`

---

**How to Structure your Redux**

```javascript
src
App
	App.tsx
	App.css
type.d.ts
index.tsx
index.css
store
	todos
		index.ts
		todos.initialState.ts
		todos.reducer.ts
		todos.slice.ts
root-reducer.ts
store.ts
```
 
**Now we are ready to start configuring our store:**

**Step 1: Create a folder `"/src/store"`**

All files related to our Redux will be placed here.

**Step 2: Create a file `"store.ts"` in `"src/store"`**

This file will contain *"configureStore"* function that is abstraction over the standart Redux *"createStore"* function and it is responsible for the store setup. If we want to use *"redux-logger"* and apply custom middleware, we need to import *"getDefaultMiddleware()"* function and spread all available props together with *"logger"*, then pass it as a prop to *"configureStore"*.

```javascript
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import logger from 'redux-logger';

import { reducer } from './root-reducer';

const middleware = [...getDefaultMiddleware(), logger];

export default configureStore({
  reducer,
  middleware,
});
```
**Step 3: Create a file "root-reducer.ts" in "src/store"**

Because we structure the app in the long run to scale, we want to have a separate *"root-reducer.ts"* file, so that we can import additional reducers.

```javascript
import { todosSlice } from './todos/todos.slice';

export const reducer = {
  todos: todosSlice.reducer
};

```
Now we do not have a *todoSlice* in our reducer, lets create it:

**Step 4: Create a folder "src/store/todos"**

This folder will contain all the logic related to *"todos slice"*.

**Step 5: Create following files: "index.ts", "todos.initialState.ts", "todos.reducers.ts", "todos.slice.ts"**

All todo's logic of the store state(interfaces, reducer, actions, todo slice)

**Step 6: Lets start with "todos.slice.ts" in "src/store/todos"**

```javascript
import { createSlice } from '@reduxjs/toolkit';
import { todosInitialState, todosReducer } from '.';

*createSlice - a function that accepts an initial state, an object full of reducer 
functions, and a slice name that automatically generates action creators and action 
types that correspond to the reducers and state.  Internally it uses createAction and createReducer* 

export const todosSlice = createSlice({
  name: 'todos', // name used in action types
  initialState: todosInitialState, // initial state for the reducer
  reducers: todosReducer,
});

export const {
  actions: { // action creators exported from todosSlice.actions available out of the box
    create: createTodoActionCreator
  },
} = todosSlice;
```

**Step 7: Then proceed with our ‘"todos.initialState.ts"’ in "src/todos"**:

```javascript
import { v1 as uuid } from 'uuid';
import { ITodo } from '../../type';

export const todosInitialState: ITodo[] = [
  {
    id: uuid(),
    desc: 'Learn Redux-ToolKit',
    isComplete: false,
  },
];
```CreateTodo.tsx:

**Step 8: Lets add missing information in "src/store/todos/todos.reducer.ts"**

*Note:*
*In order to be more consistent it is advisable, for all of the models below to have respective interface. For the purpose of this tutorial some of these parts are simplified.*

```javascript
import { PayloadAction } from '@reduxjs/toolkit';
import { v1 as uuid } from 'uuid';

import { ITodo } from '../../type';

export const todosReducer = {
  create: {
    reducer: (
      state: ITodo[],
      action: PayloadAction<{ id: string; desc: string; isComplete: boolean }>
    ) => {
      state.push(action.payload);
    },
    prepare: ({ desc }: { desc: string }) => ({
      payload: {
        id: uuid(),
        desc,
        isComplete: false,
      },
    }),
  }
};

```
**Step 9: Then exports these files in "src/store/todos/index.ts"**

```javascript
export * from './todos.reducer';
export * from './todos.initialState';
export * from './todos.slice';
```

**Connecting Redux with React Components with useDispatch and useSelector hooks**

**Step 10: Create a folder "src/components"**

All components will be placed there for now.

**Step 11: Create a folder "src/app"**

**Step 12: Move files "App.tsx" and "App.css" into "src/app"**

**Step 13: Populate "App.tsx" with following peace of code:**

```javascript
import React from 'react';
import { useSelector } from 'react-redux';

import { State } from '../type';
import { CreateTodo, TodoList } from '../components';

import './App.css';

const App = function () {
  const todos = useSelector((state: State) => state.todos);

  return (
    <div className="App">
      <div className="App__header">
        <h1>Redux Toolkit</h1>
        <CreateTodo />
      </div>
      <div className="App__body">
        <TodoList todos={todos} />
      </div>
    </div>
  );
};

export default App;
```

**Step 14: Create following files into "src/components":**

**CreateTodo.tsx:**


```javascript
import React, { FC, FormEvent, useState, ChangeEvent } from 'react'
import { useDispatch } from 'react-redux';
import { createTodoActionCreator } from '../store/todos';

interface ICreateTodoProps { }

export const CreateTodo: FC<ICreateTodoProps> = () => {
  const dispatch = useDispatch();

  const [newTodoInput, setNewTodoInput] = useState<string>('');

  const handleCreateNewTodo = (e: FormEvent<HTMLFormElement>): void => {
    e.preventDefault();
    if (!newTodoInput.length) return;

    dispatch(createTodoActionCreator({ desc: newTodoInput }));
    setNewTodoInput('');
  };

  const handleNewInputChange = (e: ChangeEvent<HTMLInputElement>): void => {
    setNewTodoInput(e.target.value);
  };

  return (
    <form onSubmit={handleCreateNewTodo}>
      <label htmlFor="new-todo">Add new:</label>
      <input
        onChange={handleNewInputChange}
        id="new-todo"
        value={newTodoInput}
      />
      <button type="submit">Create</button>
    </form>
  )
}
```

**Todo.tsx:**

```javascript
import React, { FC } from 'react'
import { ITodo } from '../type'

interface ITodoProps {
  key: string;
  todo: ITodo
}

export const Todo: FC<ITodoProps> = ({ key, todo }) => <li>{todo.desc}</li>

```

**TodoList.tsx:**

```javascript
import React, { FC } from 'react'
import { ITodo } from '../type'
import { Todo } from '.'

interface ITodoList {
  todos: ITodo[]
}
export const TodoList: FC<ITodoList> = ({ todos }) => {
  return (
    <ul className="App__list">
      <h2>My Todos:</h2>
      {todos &&
        todos.map((todo, i: number) => (
          <Todo key={todo.id} todo={todo} />
        ))}
    </ul>
  )
}
```

**Step 15: Create "type.d.ts" file into root folder:**

```javascript
export interface ITodo {
  id: string;
  desc: string;
  isComplete: boolean;
}

export interface State {
  todos: Todo[];
}
```

---

**Summary**

It’s amazing how simple is to setup Redux in 2020. We used tools Typescript, React Hooks, Redux Toolkit


Thank you for reading the article! I hope you find it useful 😊.