chore: refactor todolists reducer to use rtk

This commit is contained in:
2024-08-17 18:47:39 +02:00
parent 5067f64ec3
commit 52dbbea2fd
4 changed files with 74 additions and 104 deletions

View File

@@ -104,7 +104,7 @@ export const Todolist = React.memo(function ({
disabled={props.todolist.entityStatus === 'loading'} disabled={props.todolist.entityStatus === 'loading'}
/> />
<div> <div>
{tasksForTodolist.map((t) => ( {tasksForTodolist?.map((t) => (
<Task <Task
key={t.id} key={t.id}
task={t} task={t}

View File

@@ -1,8 +1,3 @@
import {
AddTodolistActionType,
RemoveTodolistActionType,
SetTodolistsActionType,
} from './todolists-reducer'
import { import {
TaskPriorities, TaskPriorities,
TaskStatuses, TaskStatuses,
@@ -55,9 +50,9 @@ export const tasksReducer = (
return copyState return copyState
case 'SET-TODOLISTS': { case 'SET-TODOLISTS': {
const copyState = { ...state } const copyState = { ...state }
action.todolists.forEach((tl) => { // action.todolists.forEach((tl) => {
copyState[tl.id] = [] // copyState[tl.id] = []
}) // })
return copyState return copyState
} }
case 'SET-TASKS': case 'SET-TASKS':
@@ -198,7 +193,5 @@ type ActionsType =
| ReturnType<typeof removeTaskAC> | ReturnType<typeof removeTaskAC>
| ReturnType<typeof addTaskAC> | ReturnType<typeof addTaskAC>
| ReturnType<typeof updateTaskAC> | ReturnType<typeof updateTaskAC>
| AddTodolistActionType
| RemoveTodolistActionType
| SetTodolistsActionType
| ReturnType<typeof setTasksAC> | ReturnType<typeof setTasksAC>
| any

View File

@@ -1,96 +1,90 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { todolistsAPI, TodolistType } from 'api/todolists-api' import { todolistsAPI, TodolistType } from 'api/todolists-api'
import { Dispatch } from 'redux'
import { RequestStatusType, setAppStatusAC } from 'app/app-reducer' import { RequestStatusType, setAppStatusAC } from 'app/app-reducer'
import { handleServerNetworkError } from 'utils/error-utils'
import { AppThunk } from 'app/store' import { AppThunk } from 'app/store'
import { handleServerNetworkError } from 'utils/error-utils'
export type FilterValuesType = 'all' | 'active' | 'completed'
export type TodolistDomainType = TodolistType & {
filter: FilterValuesType
entityStatus: RequestStatusType
}
const initialState: Array<TodolistDomainType> = [] const initialState: Array<TodolistDomainType> = []
export const todolistsReducer = ( const todolistsSlice = createSlice({
state: Array<TodolistDomainType> = initialState, name: 'todolists',
action: ActionsType initialState,
): Array<TodolistDomainType> => { reducers: {
switch (action.type) { removeTodolistAC(state, action: PayloadAction<string>) {
case 'REMOVE-TODOLIST': return state.filter((tl) => tl.id != action.payload)
return state.filter((tl) => tl.id != action.id) },
case 'ADD-TODOLIST': addTodolistAC(state, action: PayloadAction<TodolistType>) {
return [ return [
{ ...action.todolist, filter: 'all', entityStatus: 'idle' }, { ...action.payload, filter: 'all', entityStatus: 'idle' },
...state, ...state,
] ]
},
case 'CHANGE-TODOLIST-TITLE': changeTodolistTitleAC(
state,
action: PayloadAction<{
id: string
title: string
}>
) {
return state.map((tl) => return state.map((tl) =>
tl.id === action.id ? { ...tl, title: action.title } : tl tl.id === action.payload.id
? { ...tl, title: action.payload.title }
: tl
) )
case 'CHANGE-TODOLIST-FILTER': },
changeTodolistFilterAC(
state,
action: PayloadAction<{
id: string
filter: FilterValuesType
}>
) {
return state.map((tl) => return state.map((tl) =>
tl.id === action.id ? { ...tl, filter: action.filter } : tl tl.id === action.payload.id
? { ...tl, filter: action.payload.filter }
: tl
) )
case 'CHANGE-TODOLIST-ENTITY-STATUS': },
changeTodolistEntityStatusAC(
state,
action: PayloadAction<{
id: string
status: RequestStatusType
}>
) {
return state.map((tl) => return state.map((tl) =>
tl.id === action.id ? { ...tl, entityStatus: action.status } : tl tl.id === action.payload.id
? { ...tl, entityStatus: action.payload.status }
: tl
) )
case 'SET-TODOLISTS': },
return action.todolists.map((tl) => ({ setTodolistsAC(state, action: PayloadAction<Array<TodolistType>>) {
return action.payload.map((tl) => ({
...tl, ...tl,
filter: 'all', filter: 'all',
entityStatus: 'idle', entityStatus: 'idle',
})) }))
default: },
return state },
} })
}
// actions export const {
export const removeTodolistAC = (id: string) => changeTodolistEntityStatusAC,
({ type: 'REMOVE-TODOLIST', id }) as const changeTodolistFilterAC,
changeTodolistTitleAC,
addTodolistAC,
removeTodolistAC,
setTodolistsAC,
} = todolistsSlice.actions
export const addTodolistAC = (todolist: TodolistType) => export const todolistsReducer = todolistsSlice.reducer
({ type: 'ADD-TODOLIST', todolist }) as const
export const changeTodolistTitleAC = ({
id,
title,
}: {
id: string
title: string
}) =>
({
type: 'CHANGE-TODOLIST-TITLE',
id,
title,
}) as const
export const changeTodolistFilterAC = ({
id,
filter,
}: {
id: string
filter: FilterValuesType
}) =>
({
type: 'CHANGE-TODOLIST-FILTER',
id,
filter,
}) as const
export const changeTodolistEntityStatusAC = ({
id,
status,
}: {
id: string
status: RequestStatusType
}) =>
({
type: 'CHANGE-TODOLIST-ENTITY-STATUS',
id,
status,
}) as const
export const setTodolistsAC = (todolists: Array<TodolistType>) =>
({ type: 'SET-TODOLISTS', todolists }) as const
// thunks
export const fetchTodolistsTC = (): AppThunk => { export const fetchTodolistsTC = (): AppThunk => {
return (dispatch) => { return (dispatch) => {
dispatch(setAppStatusAC('loading')) dispatch(setAppStatusAC('loading'))
@@ -129,27 +123,10 @@ export const addTodolistTC = (title: string): AppThunk => {
}) })
} }
} }
export const changeTodolistTitleTC = (id: string, title: string) => { export const changeTodolistTitleTC = (id: string, title: string): AppThunk => {
return (dispatch: Dispatch<ActionsType>) => { return (dispatch) => {
todolistsAPI.updateTodolist(id, title).then((res) => { todolistsAPI.updateTodolist(id, title).then((res) => {
dispatch(changeTodolistTitleAC({ id: id, title: title })) dispatch(changeTodolistTitleAC({ id: id, title: title }))
}) })
} }
} }
// types
export type AddTodolistActionType = ReturnType<typeof addTodolistAC>
export type RemoveTodolistActionType = ReturnType<typeof removeTodolistAC>
export type SetTodolistsActionType = ReturnType<typeof setTodolistsAC>
type ActionsType =
| RemoveTodolistActionType
| AddTodolistActionType
| ReturnType<typeof changeTodolistTitleAC>
| ReturnType<typeof changeTodolistFilterAC>
| SetTodolistsActionType
| ReturnType<typeof changeTodolistEntityStatusAC>
export type FilterValuesType = 'all' | 'active' | 'completed'
export type TodolistDomainType = TodolistType & {
filter: FilterValuesType
entityStatus: RequestStatusType
}

View File

@@ -26,6 +26,6 @@ test('ids should be equals', () => {
const idFromTasks = keys[0] const idFromTasks = keys[0]
const idFromTodolists = endTodolistsState[0].id const idFromTodolists = endTodolistsState[0].id
expect(idFromTasks).toBe(action.todolist.id) expect(idFromTasks).toBe(action.payload.id)
expect(idFromTodolists).toBe(action.todolist.id) expect(idFromTodolists).toBe(action.payload.id)
}) })