-
-
Notifications
You must be signed in to change notification settings - Fork 72
/
store.ts
70 lines (62 loc) · 1.6 KB
/
store.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { useReducer, Reducer } from 'react';
import { createContainer } from 'react-tracked';
export type TodoType = {
id: number;
title: string;
completed: boolean;
};
type State = {
todos: TodoType[];
};
type Action =
| { type: 'ADD_TODO'; title: string }
| { type: 'DELETE_TODO'; id: number }
| { type: 'CHANGE_TODO'; id: number; title: string }
| { type: 'TOGGLE_TODO'; id: number };
const initialState: State = {
todos: [
{ id: 1, title: 'Wash dishes', completed: false },
{ id: 2, title: 'Study JS', completed: false },
{ id: 3, title: 'Buy ticket', completed: false },
],
};
let nextId = 4;
const reducer: Reducer<State, Action> = (state, action) => {
switch (action.type) {
case 'ADD_TODO':
return {
...state,
todos: [
...state.todos,
{ id: nextId++, title: action.title, completed: false },
],
};
case 'DELETE_TODO':
return {
...state,
todos: state.todos.filter((todo) => todo.id !== action.id),
};
case 'CHANGE_TODO':
return {
...state,
todos: state.todos.map((todo) => (
todo.id === action.id ? { ...todo, title: action.title } : todo
)),
};
case 'TOGGLE_TODO':
return {
...state,
todos: state.todos.map((todo) => (
todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
)),
};
default:
return state;
}
};
const useValue = () => useReducer(reducer, initialState);
export const {
Provider,
useTrackedState,
useUpdate: useDispatch,
} = createContainer(useValue);