[Redux-Toolkit] ToDoList(3): RTK로 상태관리 해보기!- 일정 관리

Cottonmycotton·2022년 11월 1일
0

상태관리

목록 보기
3/4

👀 개요

To Do List의 내용을 다른 페이지에서도 출력할 수 있도록 전역 상태관리가 필요하게 되었다. 리덕스 툴킷을 이용한 리스트 생성과 삭제 과정을 세 가지 파트에 나눠 정리해보았다. 이번 포스팅에서는 일정 관리에 관한 내용을 다뤄보려고 한다.
(모달창 구현과 DatePicker를 이용한 날짜 관리는 추후에 따로 업데이트 예정)

이전 포스팅:
(1) 스토어 및 슬라이스 생성
(2) 일정 생성

📌 순서

  1. 스토어 생성
  2. 스토어 제공
  3. 상태 슬라이스 생성
  4. 스토어에 슬라이스 리듀서 추가
    5. 리액트 내부에서 리덕스 사용하기
    (1) 일정 생성하기
    (2) 일정 관리하기

🎁 리액트 내부에서 Redux-Tookit 사용하기

  • useDispatch
    슬라이스에 등록된 액션함수를 호출하려면 useDispatch 훅을 사용해야 한다. 슬라이스에서 action을 추출해낸 뒤 액션의 이름을 추가해주면 된다. 매개변수로 전달된 값은 알아서 payload라는 필드 아래로 들어가게 된다. 데이터를 보내는 것!
  • useSelector
    리덕스 저장소에서 데이터를 추출할 수 있다. 등록한 데이터를 가져와서 사용함.

2. Checking List: To Do List 관리(처리 및 삭제)

// 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으로 바꿔보자!'- 코딩알려주는누나

깃헙 Repo

profile
투명인간

0개의 댓글