프론트엔드 데브코스 5기 TIL 70 - useEffect dependency, EventSourcePolyfill 이벤트 타입, yarn add 에러

김영현·2024년 2월 24일
0

TIL

목록 보기
81/129

useEffect dependecy

의존성배열에 있는 값이 바뀌면 useEffect를 재실행 함.
이때 의존성 배열에 있는 값이 객체라면 말이 달라진다.


출처 리액트 공식문서

객체를 사용할땐 최대한 특정 프로퍼티만 사용하거나, useEffect내부에서 만들어서 사용하자.

결론

참조형 데이터는 비교할때 조심해서 다루자!


EventSourcePolyfill 커스텀 이벤트 타입 문제

브라우저에서 지원하는 EventSource는 헤더에 토큰이 실리지 않아, 그 기능을 지원하는 EventSourcePolyfiill이라는 라이브러리를 사용했다.

이후 구현을 하면서, 특정 이벤트에 대해 핸들러를 부착해야했음.

const sse = new EventSourcePolyfill(url);

sse.addEventListener('myEvent', handler);

하지만 타입오류 발생.

왜 그런지 하고 구현체를 보니...

interface EventSourceEventMap {
    "error": Event;
    "message": MessageEvent;
    "open": Event;
}

addEventListener<K extends keyof EventSourceEventMap>(
    type: K,
    listener: (this: EventSource, ev: EventSourceEventMap[K]) => any,
    options?: any,
): void;

즉, EventSourceEventMap에는 myEvent가 없다. 따라서 타입 에러가 남.

아래처럼 제네릭으로 전달하려고 하여도, keyof라는 제약조건때문에 불가능.

addEventListener<{ 'myEvent': MessageEvent }>....

어떻게 할까?

라이브러리의 타입을 수정한다. (안됩니다~)

타입을 수정할순 있다.

interface EventSourceEventMap {
    "error": Event;
    "message": MessageEvent;
    "open": Event;
  	"myEvent": MessageEvent;
}

그러나 라이브러리를 다시 설치하면 날아간다.

as키워드를 사용한다.

잘 찾아보니 addEventListener의 타입이 하나 더 있었다.

interface EventListenerObject {
    handleEvent(evt: Event): void;
}

interface EventListener {
    (evt: Event): void;
}

type EventListenerOrEventListenerObject = EventListener | EventListenerObject;

addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: any): void;

오! type이 제약조건을 만족하지 않아도 된다.
하지만, MessageEvent를 받을 순 없다...😥

그래서 결국!

const handleInitConnect = (e: Event) => {
  const messageEvent = e as MessageEvent;
  const data = JSON.parse(messageEvent.data);
  
  setData(data);
};

위처럼 Event인척하고 받아와서 as키워드를 이용하여 MessageEvent로 컴파일러에게 이벤트 타입을 명시해주었다.

이게 맞나 싶지만, 일단 문제 해결. as키워드를 쓰지 않고 할 수 있는 방향을 찾아봐야겠다.


yarn add 에러 The remote archive doesn't match the expected checksum

라이브러리 타입 수정한 뒤, 다른 패키지 설치하려고 yarn add ...썼을때 나온 문제!

yarn cache clean --all로 캐시 날리고 설치하니 해결

profile
모르는 것을 모른다고 하기

0개의 댓글