To Do List의 내용을 다른 페이지에서도 출력할 수 있도록 전역 상태관리가 필요하게 되었다. 리덕스 툴킷을 이용한 리스트 생성과 삭제 과정을 세 가지 파트에 나눠 정리해보았다. 이번 포스팅에서는 일정 관리에 관한 내용을 다뤄보려고 한다.
(모달창 구현과 DatePicker를 이용한 날짜 관리는 추후에 따로 업데이트 예정)
이전 포스팅:
(1) 스토어 및 슬라이스 생성
(2) 일정 생성
useDispatch
useSelector
// src/pages/CheckingList/CheckingList.js
import React, { useState } from 'react';
import CheckingModal from '../../components/CheckingModal/CheckingModal';
import CheckingListContainer from '../../components/CheckingListContainer/CheckingListContainer';
import DoneListContainer from '../../components/DoneListContainer/DoneListContainer';
import { useDispatch, useSelector } from 'react-redux';
import { toDoActions } from '../../App/toDoListSlice';
const CheckingList = () => {
// 액션함수 불러오기
const dispatch = useDispatch();
// slice에서 작성한 toDoList데이터를 불러와 toDos라는 변수에 저장
// In Progress 패널에 출력될 데이터
const toDos = useSelector(state => state.toDo.toDoList);
// slice에서 작성한 toDoList데이터를 불러와 done이라는 변수에 저장
// Done 패널에 출력될 데이터
const done = useSelector(state => state.toDo.doneList);
const [removeList, setRemoveList] = useState([]);
// Done패널로 이동된 일정들을 삭제할때 사용될 모달
const [modal, setModal] = useState(false);
// 체크박스 체크 시 체크여부와 체크된 list를 매개변수로 전달해준다.
// filter함수를 이용하여 체크가 되지 않은 새로운 배열을 변환한 뒤 addToDo 액션 함수에 전달, toDos의 값을 업데이트 시켜준다.
// progressToDo함수는 일정이 완료된 list를 In Progress패널에서 Done패널로 이동시키기 위해 작성되었다. 체크된 list를 매개변수로 전달하여 화면에 출력
const onCheckedList = (checked, list) => {
if (checked) {
const filteredList = toDos.filter(el => el.id !== list.id);
dispatch(toDoActions.addToDo({ data: filteredList }));
dispatch(toDoActions.progressToDo({ data: [...done, list] }));
}
};
// 삭제버튼을 클릭하면 해당 일정의 아이디 값이 전달되고 removedList에 저장된다
// 삭제여부를 확인하는 모달창이 출력된다
const onRemove = id => {
setRemovedList(id);
setModal(true);
};
const closeModal = () => {
setModal(false);
};
// Done 패널로 이동된 일정들을 완전히 삭제시키기 위해 작성된 함수
// removedList에 저장된 아이디값과 done에 있는 데이터 아이디값이 일치하는 값을 제외한 데이터를 화면에 출력시킴
// 즉, 삭제버튼 클릭시 삭제여부를 확인하는 모달창이 출력, '삭제할게요' 버튼 클릭 시 onRemovedList 함수가 작동되면서 위 설명과 같은 로직이 실행된다
const onRemovedList = () => {
const filteredList = done.filter(list => list.id !== removedList);
dispatch(toDoActions.progressToDo({ data: filteredList }));
setModal(!modal);
};
return (
<main className="flex flex-col justify-center items-center max-w-100% h-750px">
{modal ? (
<CheckingModal
closeModal={() => closeModal()}
onRemovedList={() => onRemovedList()}
onClick={() => {
closeModal();
onRemovedList();
}}
/>
) : null}
(...생략)
<div className="flex w-[60%] h-[100%] items-start justify-between mt-50px">
<div className="flex flex-col items-start w-[45%] h-100% p-30px bg-transparent rounded-[10px] overflow-auto">
<p className="text-20px text-deep-gray font-semi-bold">
In Progress
</p>
<div className="flex flex-col items-center w-100% my-30px">
{toDos.map((list, index) => {
return (
<CheckingListContainer
key={index}
id={list.id}
userToDo={list.userToDo}
startDate={list.startDate}
endDate={list.endDate}
onChange={event => {
onCheckedList(event.target.checked, list);
}}
// done에 아이디 값이 있으면 true, 없으면 false인데 checked값을 설정해주지 않으면 체크표시가 다음 데이터에 전달되므로 checked값을 설정해줘야 한다.
checked={done.includes(list.id) ? true : false}
/>
);
})}
</div>
(...생략)
<div className="flex flex-col items-start w-[45%] h-100% p-30px bg-transparent rounded-[10px] overflow-auto">
<p className="text-20px text-deep-gray font-semi-bold">Done</p>
<div className="flex flex-col items-center w-100% my-30px">
{done.map((list, index) => {
return (
<DoneListContainer
key={index}
id={list.id}
userToDo={list.userToDo}
startDate={list.startDate}
endDate={list.endDate}
onClick={() => onRemove(list.id)}
/>
);
})}
</div>
</div>
</main>
);
};
export default CheckingList;
참고자료:
Redux-Toolkit 공식문서
'아직도 옛날 리덕스 쓴다고..? 옛날 리덕스를 최신 리덕스 Toolkit으로 바꿔보자!'- 코딩알려주는누나