Todo 기본 기능 완성

최경락 (K_ROCK_)·2022년 5월 31일
0

  • 여차저차 Todo 기본 기능에 대한 작성이 끝이 났다.
  • 표시되는 항목을 크게 Input, Todo, Done 으로 나누어 볼 수 있을 것 같다.
const [todoList, setTodoList] = useState<string[]>([]);
// todo 들을 저장하는 상태
const [doneList, setDoneList] = useState<string[]>([]);
// 완료된 todo 들을 저장하는 상태
  • 현재 todoListdoneList 는 App 컴포넌트에서 상태로 저장된다.
  • 두 상태 모두 문자열이 저장된 배열이나, 추후 리팩토링 과정을 거치면서 하나의 상태로 통합하고 객체를 가진 배열로 저장할 예정이다.
  • 아마 아래와 같은 형태로 저장하게 되지 않을까 싶다.
{
  status : done, // or todo
  content : 비타민챙겨먹기
}

Input

  • todoList 상태와 그 갱신함수인 setTodoList 함수를 props 로 전달받는다.
  • input 태그를 통해 입력된 값을 onChange 이벤트를 통해 변경될때마다 inputValue 라는 상태에 저장한다.
<input
  type="text"
  value={inputValue}
  onChange={(e) => setInputValue(e.target.value)}
/>

todo에 추가하기

  • 추가 버튼을 클릭한 경우 혹은 엔터를 입력하는 경우에 addTodo 함수를 실행시키고, 갱신함수를 통해 기존 todoList 상태에 저장된 값들 뒤에 현재 inputValue 를 추가하고, inputValue 를 초기화한다.
const addTodo = (
    e:
      | React.FormEvent<HTMLFormElement>
      | React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) => {
    e.preventDefault();

    if (!inputValue) return;
    setTodoList([...todoList, inputValue]);
    setInputValue('');
  };
  • 코드 상에서 e 에 지정된 타입들은 작성한 이벤트 핸들러의 매개변수에 커서를 올려보면 표시된다.

TodoList

  • 현재 TodoList 라는 상위 컴포넌트에서 Todo, Done 이라는 하위 컴포넌트로 props를 전달하고, 위의 사진처럼 각각을 나누어 렌더링하는 방식을 취하고 있다.
  • App 에서 전달받는 props는 다음과 같다.
interface IProps {
  todoList: string[];
  setTodoList: Dispatch<SetStateAction<string[]>>;
  doneList: string[];
  setDoneList: Dispatch<SetStateAction<string[]>>;
}
  • 여기서 전달받은 todoListdoneListmap을 이용하여 컨텐츠들을 렌더링 시켜주었다.
    Todo, Done 컴포넌트
{todoList.map((content, idx) => {
  return (
    <Todo key={idx}
    //이외의 props 생략
    />
  );

Done 도 동일한 형태로 렌더링해주었다.

  • 단축비교를 이용한 조건부 렌더링을 이용하여 저장된 값이 없는 경우를 안내했다.
{todoList.length === 0 && <div className="empty">비어 있습니다.</div>}

Todo

  • TodoList 에서 전달받는 props는 다음과 같다.
interface IProps {
  content: string;
  idx: number;
  todoList: string[];
  setTodoList: Dispatch<SetStateAction<string[]>>;
  doneList: string[];
  setDoneList: Dispatch<SetStateAction<string[]>>;
}
  • 코드를 작성하면서 떠올려 봤을 때 해당 todo를 삭제하거나, 완료한 상태로 만드는 과정이 필요하다고 생각했다.

todo 삭제하기

  • 갱신함수와 filter 함수를 이용하여 삭제를 구현하였다.
  • 전달된 인덱스와 선택된 요소의 인덱스가 동일하지 않은 요소만 반환한다.
const deleteTodo = () => {
    setTodoList(
      todoList.filter((todo, todoIdx) => {
        return idx !== todoIdx;
      })
    );
  };

todo 완료하기

  • 삭제와 같은 방식으로 구현하지만, doneList 에 해당 데이터를 추가하는 과정을 추가했다.
const completeTodo = () => {
    setDoneList([...doneList, todoList[idx]]); // 요기
    setTodoList(
      todoList.filter((todo, todoIdx) => {
        return idx !== todoIdx;
      })
    );
  };

Done

  • TodoList 에서 전달받는 props는 다음과 같다.
interface IProps {
  content: string;
  idx: number;
  doneList: string[];
  setDoneList: Dispatch<SetStateAction<string[]>>;
}
  • 완료된 todo 에 대해서는 삭제만 하면 된다라고 판단하여 삭제기능만 Todo 컴포넌트와 동일하게 구현해주었다.
const deleteDone = () => {
    setDoneList(
      doneList.filter((done, doneIdx) => {
        return idx !== doneIdx;
      })
    );
  }; 
  • 다만, 완료된 목록의 정리를 한번에 해줄 수 있는 기능이 있으면 좋을 것 같있기에 TodoList 컴포넌트에 아래와 같이 함수를 작성하여 전체삭제를 추가해주었다.
const clearDoneList = () => {
    setDoneList([]);
  };

+

  • Redux를 사용할 생각은 하고 있으나, 먼저 Props Drilling 으로 상태를 전달하고, 추후에 차근차근 적용시킬 예정이다.
  • 아마 과정으로 표시하면, 저장되는 형식 수정 → Redux 적용 → 로컬 스토리지 적용 → 새 기능 추가 가 되지 않을까 싶다.

0개의 댓글