[개발일지] Dispatch, Non-null assertion operator in TypeScript

김선종·2021년 11월 16일
1

오늘 한 일

  • 메신저 어플리케이션에서 친구 목록, 채팅방 목록에 대해 Context 적용

우선 에러부터 알아봅시다

  • useReducer 사용 시에, dispatch의 타입이 자꾸 오류를 발생시켰다.
  • find, filter 함수 사용 시, 리턴 값에서 undefined를 포함할 수 있음에 따라 타입 에러를 발생시켰다.

리듀서는 오늘도 나를 괴롭혔다

context에 state와 reducer를 포함해서 넘겨주려고 하니, 자꾸 리듀서의 타입에 대해서 에러가 무한히 발생하는 것이다. 리듀서 자체는 (state, action) => state 의 형태를 가지고 있는데, 이를 useReducer의 dispatch 함수로 넣어주면 자꾸 타입이 Dispatch<any>가 되어 에러가 났다. Dispatch(action) => void의 형태를 갖는다.

(사진을 좀 찍어놓을 걸 고치는데 급급해서...)

Flux를 제대로 이해하기부터,,,


Flux 패턴 으로 검색을 하면 100개의 블로그 중에 99개가 이 사진을 쓴다.

  • 사용자의 action을 dispatcher가 포착한다 (dispatch)
  • dispatcher는 리듀서에서 정의된 방식에 의해 사용자의 action을 처리한다

정도가 flux의 기본적인 동작 방식이라고 할 수 있다.
따라서, dispatcher는 사용자의 동작을 포착해서 리듀서에게 수행할 것을 지시하는 역할이다.

짧은 깨달음

const [chatroomContext, chatroomListDispatch] = useReducer(
    chatroomListReducer,
    CHATTINGS
  );

보통 useReducer는 이런 패턴으로 선언하는데, 나는 그동안 이러한 선언 형태 때문에 리듀서가 곧 dispatcher구나...! 라고 잘못 이해하고 있었다 (남탓하기)
따라서 dispatch 함수 자체에는 어떠한 리턴값이 존재하지 않는다.

export const ChatroomContext = createContext<{
  chatroomContext: chatroomList;
  chatroomListDispatch: Dispatch<chatroomAction>;
}>({
  chatroomContext: CHATTINGS,
  chatroomListDispatch: () => null,
});

find, filter도 나를 괴롭게해,,,

context를 다룰 custom hook을 만드는 과정에서, 배열중 한개의 원소를 찾기 위해 filter를 썼었다. 근데 filter는 조건에 만족하는 모든 원소들을 배열의 형태로 가지기 때문에 객체 형태의 타입을 리턴한다고 명시했다가 계속해서 에러가 나는 것이었다.


왠지 저번에도 겪은 에러라서 처음에는 끝에 [0]을 붙여서 해결해보았다. 하지만 뭔가 간지가 안나니까,,, find를 사용해서 써 봤는데 그때는 또,,,


흠... 로직 상 undefined일 수 없으나, find 함수의 특성상 그럴 수 있기 때문에 이러한 에러가 발생하는 것 같다.

무조건 non-null 하다고 우기는 방법

타입스크립트에서 이런 경우에, 해당 값이 non-null 하다고 단언하는 방법이 있다. non-null assertion operator를 사용하는 방법이 있는데, 무언가 nullable한 값 뒤에 !를 붙여주면 된다.

const getSingleChatroom = (friendId: number): chatroom => {
    return chatroomContext.find((chatroom) => 
        chatroom.friendId === friendId)!; // 이렇게
  };

그렇다면 무조건 non-null 한 값을 가지는 걸로 타입스크립트가 인식하게 된다.

TIL

  • 뭐든 기초 개념을 확실히 알고 들어가는게 좋겠다
  • 타입스크립트는 빈틈이 없다
profile
개발자가 되고싶다 열심히하자

0개의 댓글