Tips to build a Todo app with react, redux-saga, typescript and react-bootstrap — 1
As a developer, I want to build a React To-do List App with react, redux-saga, typescript and react-bootstrap. This is not a step by step tutorial, but I would like to cover some tips on how I developed this project. For example, how the project is designed, how the data model is built, how to do the testing, and how to integrate with redux-saga.
I come across Redux-Saga — An intuitive Redux side effect manager. | Redux-Saga, and I was impressed. So I was going to create a project to use it.
Before I started the project, I did some research on react, todo app, and redux. I found that a lot of materials are
obsolete: A lot of projects are not using hooks or not using typescripts. So I’d like to create a project includes this features: react hooks, typescript, redux, redux-saga, and react-bootstrap. I found three good resources which helped me to polish my new project: Build a GitHub Jobs App With React Hooks — YouTube, Beginning our React todo list — Learn web development | MDN (mozilla.org) and Build a To-do List App with React.js | Enlight.
Design — UI
The first thing come to my mind is: how to UI look like. I scratched it like below. It includes three container:
- ToDoAdd. UI to allow user to add a todo
- ToDoFilter: UI to allow user to filter todos
- ToDoList: UI to list todos, allow user to toggle todo and delete todo
Design — Model
Data model is the minimum ‘state’ you need to keep to recover the same UI from another machine. Thinking in React — React (reactjs.org) and Lifting State Up — React (reactjs.org) are a good starter place for you to build your data model from UI. Because of the introduction of react hooks and redux store, it makes things more easy: I don’t need to care about too much about the hierarchy of the components, and I don’t need to lifting state up. I only need to identify the minimum state which I can replay the UI in another machine. In this UI, I identified these:
- Filter string, filter criterial(show all/only active/only completed)
- Todo list. Each todo includes: todo description, id and isCompleted flag.
Design — Model — Data Slices
Based on the data model. I would like to organize my data into two data slices(see createSlice | Redux Toolkit):
- the filter slice which includes filter string, and filter criterial
- the todos slice which includes the list of todos.
The data model are saved to redux store. In redux, the only way to change the model in store is to create an action, and dispatch the action to store. For the todos data slice, I would like this features:
- load and save state from storage. Because load/store the data may take some time, and may be async. So I add loadToDoSuccess and loadToDoError.
- addTodo, deleteToDo, and toggle the complete flag.
Code-Create project and add dependencies
npx create-react-app todo-react — template typescript — use-npm
npm install react-redux redux-saga @reduxjs/toolkit
npm install react-bootstrap bootstrap
npm install prettier
I would like to have these folders in my project:
- apis. communicate with external api
- slices. redux createSlice
- types. interface for data model, data slice state, RootState
- selectors. used by useSelector(react hook) to retrieve the data from store in any component.
- sagas. side effects. For example: if use performed add todo, place save it to storage. if loadToDo is dispatched, please read it from storage and update the state.
- have index.ts in sagas, selectors, slices. then it’s easy to be imported like this
2. For react component, CamelCase for both file name and component name. For example: ToDoList
3. For redux, actions, use camelCase. For example: loadToDo
When the react project is created from template, set baseUrl like below in tsconfig.ts to avoid
../ in your import. When react project is created, you can’t modify paths until you run ‘npx run eject’, so you will hit error like Add baseUrl and paths in tsconfig.json and jsconfig.json · Issue #5645 · facebook/create-react-app (github.com)
In Design — Model — Data Slices, two data slices are created. so create two selectors for them, and each per slice.
Based on Design-Model-Actions, it’s time to create reducers per action in each data slice
Testing and react saga
To be continued.
demo site: React App (licanhua.github.io)