[프로젝트] todo-service calendar 회고

arrrrrr·2023년 4월 10일

React 공부중 🎽

목록 보기
16/16
  • 진행기간: 4/7 ~ 4/9

초기 todo service를 기획할 때 중요도 low로 지정했던 날짜 선택 컴포넌트를 추가해보았다.
라이브러리를 쓰지 않고 직접 달력을 만드는 과정은 어렵다고 들었는데 막상 해보니 레퍼런스도 많고 하나씩 그려지는 과정이 재미있어서 즐겁게 진행할 수 있었다.

TIL

📆 4/7(금)

  • 레퍼런스를 찾아보면서 피그마로 디자인을 잡았다.

📆 4/8(토)

  • 클릭으로 날짜 선택이 가능한 캘린더 컴포넌트를 구현했다.

🔫 어려웠던 점

1. 클로저

문제상황

날짜를 클릭하면 이벤트 핸들러로 선택한 day의 값을 넘겨줌 → 선택 날짜가 값으로 출력될 것으로 기대함 → 하지만 월별로 동일한 하나의 날짜가 출력됨.

원인

자바스크립트에서 이벤트 핸들러는 비동기적으로 실행되어 day의 변수 값은 이벤트 핸들러가 실행되는 시점의 값으로 할당된다.

여기서 내 코드의 문제는, day 변수값이 이벤트 핸들러가 선언된 시점의 값으로 할당될 것이라고 생각했던 점이다. 그래서 이벤트 핸들러가 실행될 때마다 day의 변수 값이 항상 최신 값으로 평가되어 코드가 의도대로 동작하지 않았다.

// 이전 코드
onClick={() => onDateClick(day)}

해결

let cloneDay = day 코드를 추가하여 이벤트 핸들러가 항상 동일한 상수 값을 참조할 수 있도록 하였다. 이벤트 핸들러가 실행되는 시점에 day의 값이 변해도 cloneDay는 이전의 값을 유지하기 때문에 문제가 해결되었다.

📆 4/9(일)

  • 날짜 선택 컴포넌트를 create modal, edit modal에 연결했다.
  • 선택된 날짜 기준으로 post에 d-day가 생성되도록 post 컴포넌트를 수정했다.

🔫 어려웠던 점

1. auto batching

아직도 오토 배칭으로 애를 먹지만 😇 이전에는 원인도 몰라 쩔쩔 맸다면 지금은 원인을 떠올리고 스스로 해결할 수 있어서 뿌듯했다.
문제

  • 하나의 핸들러 내에서 state 변경 관련 코드 2줄을 작성했다.
  • 그래서 아랫줄 코드는 위에서 변경된 state 값에 의존한다.
  • 하지만 state 변경은 하나의 함수가 종료된 후에 auto batching되기 때문에 dispatch 문에서 참조하는 state는 변경전 값이다.
    // 이전 코드
    const onDateClick = (day) => {
            setSelectedDate(day);
            dispatch(setDate(selectedDate.toISOString()));
            // console.log(`선택 날짜: ${formatted} - ${typeof formatted}`);
        };

해결

디버깅 과정에서 배운 내용

  • useSelector는 state가 변하는 즉시 값을 새로 가져온다. 그래서 리렌더링이 발생한다.
    		// 변경 코드
    const onDateClick = (day) => {
            setSelectedDate(day);
            dispatch(setDate(day.toISOString()));
            // console.log(`선택 날짜: ${formatted} - ${typeof formatted}`);
        };

2. redux action payload

A non-serializable value was detected in an action, in the path: payload.

선택한 날짜를 store에 저장하는 과정에서 마주한 에러이다. Redux 상태(state)에 직렬화할 수 없는(non-serializable) 값이 포함되어 있는 경우 발생한다고 한다.

  • 리덕스의 상태에는 직렬화된 값만 저장 가능하기 때문이다.
  • Redux Toolkit에서 직력화가 아닌 값을 찾아낼 수 있는 이유는
    createSlice 함수의 reducers 항목에 정의한 리듀서 함수가 액션을 처리할 때, 페이로드의 직렬화 여부를 체크한다.
    createSlice함수의 reducer 내부에서 immer 라이브러리를 사용하고 있기 때문이다. immer가 불변성을 관리한다.

시연 화면

  • post에서 d-day를 보여준다.
  • todo 생성시 날짜 선택이 가능하다.
  • 날짜 수정이 가능하다.
  • 월 이동은 스크롤로 가능하다.

0개의 댓글