Tips to build a Todo app with react, redux-saga, typescript and react-bootstrap — 2
This is a follow up on Tips to build a Todo app with react, redux-saga, typescript and react-bootstrap — 1 | by Canhua Li | Nov, 2021 | Medium
Source code: licanhua/react-todo: A todo project with `react` + `typescript` + `redux-saga` + `react-bootstrap` (github.com)
Module-Actions
In last chapter, we created actions and the todo reducer slice like below.
There are three kinds of actions:
- data update only action. For example, loadToDosError and loadToDosSuccess.
- command only action. For example, saveToDos.
3. both data update and command action. For example: loadToDos. It first reset the data, then execute the command.
No matter the action is updating data or executing a command. They are dispatched to the store in the same way.
In reality, most of time, the command is async function. If you are using redux thunk middleware, you can refer to Redux Fundamentals, Part 6: Async Logic and Data Fetching | Redux to see how the async command is dispatched and handled. I will discuss how saga receive the command and execute it in next chapter.
Redux-saga
In my opinion, redux-saga is the soldiers, they are always standby and wait for the commander’s order. For example, the commander said: moveToTheVillage in half an hour. After the soldier take
the order, he acknowledge the command, and then drive to the village, then report the status: moveToTheVillageComplete. For some reason, he didn’t make it, then he reported: moveToTheVillageTimeout.
So the execution of the soldier is represented as a saga like this
And the soldier is waiting for the order like this:
And the commander send out the order like this:
Keep saga clean
saga should be very clean, and always keep the actual execution in a function. Otherwise it’s hard to do the testing, and lost the best feature redux-saga give you.
like api.saveToDos, it may only have one line of code
localStorage.setItem(TODOS, JSON.stringify(todos));
Don’t have above line in the saga, but put it into a function like api.saveToDos.
then you are able to test the saga like this
Saga Testing
You can refer to my code src\sagas\index.test.ts
. also Error Handling | Redux-Saga and Testing | Redux-Saga are good for you to start.
Component/Container testing
Because the nature of using hooks(useSelector/useDispatch) in React component. Below are good candidates for you:
Testing: React hooks, Redux and Jest — Tom Szpytman — Medium
reactjs — How to test a component using react-redux hooks? — Stack Overflow
import * as redux from 'react-redux'
const spy = jest.spyOn(redux, 'useSelector')
spy.mockReturnValue({ username:'test' })
jest.mock('react-redux', () => ({
useSelector: jest.fn(),
useDispatch: () => mockDispatch
}));