1.9 React masterClass (ToDoList final)

hun2__2·2022년 1월 9일
0

Have a fruitful vacation

목록 보기
13/24

먼저!
어제 하다만 ToDoList부터 마무리를 시작했다.

현재까지는 toDo를 작성할때 "TO_DO" category로 고정을 시켜놨지만 내가 원하는 category로 들어가도록 변경해주자

먼저 CreateToDo에서 categoryState의 값을 받아와 toDo를 생성할때 category가 categoryState의카테고리중 하나일 수 있게 바꿔준다.

  const setToDos = useSetRecoilState(toDoState);
  const category = useRecoilValue(categoryState);
  const valid = ({ toDo }: IForm) => {
    console.log(toDo);
    setToDos((oldToDos) => [
      { text: toDo, id: Date.now(), category },
      ...oldToDos,
    ]);
    setValue("toDo", "");
  };

(ES6문법에 의해서 category: category 처럼 같은 단어는 category 하나로 대체할 수 있다)

이렇게 하면 error가 나는데
그 이유는 setToDos로 변경해주려는 toDoState의 state의 category타입은 IToDo[]로 "TO_DO" | "DOING" | "DONE" 라고 정해져있지만 categoryState 에서 받아온 값은 단순한 string값이기 때문이다.

따라서 categoreStrate의 state값을 단순한 string이 아닌 "TO_DO" | "DOING" | "DONE" 로 변경해준다.
타입을 변경하는 3가지 방법이있는다.

먼저

export const categoryState = atom<"TO_DO" | "DOING" | "DONE">({
  key: "categoryState",
  default: "TO_DO",
});

단순히 들어갈 타입을 넣어주는 것.

조금 더 깔끔하게

export const categoryState = atom<IToDo["category"]>({
  key: "categoryState",
  default: "TO_DO",
});

우리가 원하는 타입이 IToDo의 category의 타입이므로 대괄호표기법을 이용해서 받아오는것

세번째로는 중복되는 타입을 변수처럼 새로만들어서 넣어주는것

type categorys = "TO_DO" | "DOING" | "DONE"

export interface IToDo {
  text: string;
  id: number;
  category: categorys;
}

export const categoryState = atom<categorys>({
  key: "categoryState",
  default: "TO_DO",
});

마지막으로는 열거형 타입인 enum을 사용해서 category list를 작성해준다.
이게 좋은 점은 type으로 만들어주면 3개가 세트가되서 그 중 하나만 따로 이용할수 없는데 enum을 사용하게 되면 그 안의 값들을 개별로 사용해서 타입을 지정해 줄 수 있다.
cf) 기본적으로 enum은 열거형 타입으로 내가 넣은 string값을 number로 반환한다. 즉, 반환값은 string이 아니라 number이다.
필요하다면 반환값을 내가 원하는 것으로 변경할 수 있다.

export enum Categories {
  "TO_DO" = "TO_DO",
  "DOING" = "DOING",
  "DONE" = "DONE",
}

이렇게 각 값의 value를 지정해주면

반환값이 바뀌는것을 알 수 있다.

내 생각에는 한번 재사용되면 그냥 두번째 방법으로 여러번 반복되면 변수처럼 만들어서 넣어주는 것이 가장 좋을 것 같고 여러개list값이 필요하고 그중 일부를 사용할 때는 enum이 좋은 것 같다.


먼저 type을 이용해서 category의 타입도 지정해보면 CreateToDo의 error는 해결되었다. 하지만 타입을 지정해줬기 때문에 ToDoList에서 setCategory를 할때 error가 생긴다. ![](https://velog.velcdn.com/images%2Fjae-hun-e%2Fpost%2F51f0572a-fa54-42cb-83a1-5eca6d17b986%2Fimage.png) 이전과 같은 이유로 categoryState에서 받아오는 category의 타입은 "TO_DO" | "DOING" | "DONE" 로 지정되었지만 < option value="TO_DO">와 같이 넘겨받는 value값은 단순히 string이기 때문이다. 나중에 해결하고 일단 as any로 넘어가자... (cf as any를 뒤에쓰면 어떤 타입이든 상관없어진다. 그래서 error는 해결되지만 어떤 타입이든 상관없으면 typescript를 쓸 필요가 없지... any는 최대한 지양하고 없에주자!)

그러면 이제 입력할때 category도 지정해 줄 수 있다!

이제 동작이 되는 것을 확인했으니 코드를 더 깔끔하게 고쳐보면 eunm을 이용해서 여기저기 퍼저있는 "TO_DO", "DOING", "DONE" 들을 모두 바꿔줄수 있다.
string을 직접쓰는것은 실수할 확률이 높으므로 enum타입에만 string 값으로 category 종류를 만들어 주고 필요할때 enum에서 가져와쓰는것이 안전하다.

여기서 새로운 error가 생겼다.
잘 바뀌고 category도 잘 들어가지지만 select로 category를 변경하면 안뜬다
왜지..?
비교해주기 위해 싹다 console.log를찍어봤다.

그냥 생성할 때는 카테고리가 number로
버튼 눌러줘도 카테고리가 number로 잘 변경된다.

근데 select로 변경해주면 카테고리에 카테고리number값이 담긴 string이 들어간다.

역시나 event에 as any로 타입을 지정해줬던 select부분에서 error가 났던 것이다..
any는 피하자....

확인해보니 value에 string타입이 들어가 있다.

그래서 number로 강제 형변환을 해봤지만

        <select onInput={onInput} value={category}>
          <option value={Number(Categories.TO_DO)}>To Do</option>
          <option value={Number(Categories.DOING)}>Doing</option>
          <option value={Number(Categories.DONE)}>Done</option>
        </select>

그래도 안된다... 형변환이 안 먹힌다?
왜인진 모르겠지만 Number을 사용해도 value값에 string값이 들어간다.

그래서

  const onInput = (event: React.FormEvent<HTMLSelectElement>) => {
    setCategory(+event.currentTarget.value);
  };

cf)
String -> Number 형변환하는 방법 Number(value) || +value
Number -> String 형변환하는 방법 String(value) || value + ""

이렇게 categoryState를 변경해줄때 형변환을 시켜서 넣어주었다.

이제 정상적으로 작동하지만 찝찝하다...

왜일까? 찾아보자!

input받는 모든 값은 string으로 바뀐다는 것을 알게되었다!

그리고 추가로 삭제기능과 localstorage에 todolist를 저장해서 바로 띄울 수 있도록 해보자



그 전에 내일부터 python 챌린지를 하기 위해서 미리 예습하자!


ps. 요즘 자꾸 아침에 일어나는것을 못한다... 일부러 일찍 자도 못일어난다... 정확하게 말하면 일어났다가 알람끄고 다시 잔다;;; 의지가 많이 약해진것 같다ㅜ 다시 나사 조이자! 원래 계획보다 늦어졌자나,,, 그리고 계획을 조금 수정하기로 했다 이번방학의 주공부 테마는 영어였는데 코딩에 초점이 맞춰져버린느낌이있다ㅜ 그래서 1월까지 react JS 공부를 빡시게 하며(노마드, ndemy 둘다 끝내자) TS로 내 앱에 추가해서 마저 만들고 2월에는 코딩 비율을 줄이고 영어공부를 빡시게 해봐야겠다. 책도 사고, 단어 암기장도 만들고 하루에 끝낼 스크랩트도 정하고 계획적으로 10시간 이상 영어에 투자해야겠다!!! 열심해 해보자

react JS 강의를 듣고나서 내일부터 시작할 파이썬 챌린지를 위해서 강의를 조금 들어봤다. 파이썬 문법 다 까먹고있었는데 다시 리마인드 된 느낌이 있고 내일부터 웹스크래핑을 들어보면서 최대한 빠르게 강의를 끝내고 react JS를 주로 하며 6시 이후에 챌린지 과정을 하면서 파이썬 공부도 병행해야겠다.

모든 계획에 선행되야 하는게 부지런함과 하루의 시작을 앞당기는 것이다! 내일부터는 기상 시간을 체크해가면서 점점 앞당길것이다!!! 홧팅홧팅!!

profile
과정을 적는 곳

0개의 댓글