오늘의 할 일 / Axios CancelToken, useRef

lim1313·2021년 12월 2일
0
post-thumbnail

🍊 오늘의 할 일

🍪 최소 Task

  • 신청하기 서버통신 구현
  • 지도 마커 생성
  • 지도 마커 클릭 시 모달 open 구현
  • axios.CancelToken 구현을 통해 불필요한 통신 취소
  • 가이드 카드 선택 시, 시각적으로 구분 가능한 구현

🍊 오늘의 정리

🍉 Axios CancelToken

axios.CancelToken

문제상황

Triplus 지도 페이지에서는 지도가 이동, 확대, 축소 되었을 때마다 서버에 GET 요청을 보내게 된다. 즉, 유저가 빠르게 지도의 위치를 변경하거나 하면 짧은 시간에 많은 서버 요청을 보내게 되는 것이다.

짧은 시간에 많은 axios 요청이 발생하게 되면, 이미 필요없어진 요청에 대한 응답을 받게 된다.

이를 방지하기 위해 동일한 요청이 발생한 경우, 이전 요청을 취소할 수 있는 방법을 찾아보았다.

문제해결

이를 위해 axios.CancelToken를 사용하였다.

사용방법은 생각보다 간단하였지만...
이것이 나의 3시간을 삭제시켜버렸다.

const CancelToken = axios.CancelToken;
let cancel;

if (cancel !== undefined) {
      cancel('cancel');
    }


axios
      .get(
        `${http}/map`,
         { latLngparams }, 
        {
          cancelToken: new CancelToken((c) => {
            cancel = c;
          }), //=> 잘못된 위치
        }
      )
      .then((res) => res.data.guideCardList)
      .catch((err) => {
        if (axios.isCancel(err)) {
          console.log('cancel', err);
        } else {
          console.log('err', err);
        }
      });

예제 코드와 동일하게 작성하고 모든 필요한 코드를 작성해주었지만 이상하게 모든 요청이 cancel되지 않고 처리되는 것을 볼 수 있다.

간단한 환경에서 구현해 보기

이 문제의 해결방법을 찾아다녔지만, 분명 모든 요구사항을 작성해주었고, 모든 레퍼런스가 내 코드와 동일하였다.
나는 kakaomap API와 함께 사용하였기 때문에, 이것때문인가? 라는 의문과 함께 모든 조건을 제외한 간단한 환경에서 동일한 코드를 적용해 보았다. 그 결과 내가 작성한 로직이 맞는 것이었다.

다만, 여기서 params를 제외시켜주었는데, 이때 깨달았다. 인자의 위치가 틀렸구나. 2번째 인자로 {cancelToken: new CancelToken((c) => {cancel = c})} 위치를 바꾸어 주니 정상동작하는 것을 확인할 수 있었다.

axios
      .get(
        `${http}/map`,
        {
        cancelToken: new CancelToken((c) => {
        cancel = c;
       }),
       params,
  	  }
      )
      .then((res) => res.data.guideCardList)
      .catch((err) => {
        if (axios.isCancel(err)) {
          console.log('cancel', err);
        } else {
          console.log('err', err);
        }
      });

인자의 위치를 바꿔 해결하였다.

처음 적용하는 기능은 간단한 구현일지라도, 조금은 단순한 환경 속에서 테스트를 해보는 것이 더 현명한 방법일지도 모르겠다.

🍉 useRef & addEventListener

문제상황

가이드 필터링을 선택하여 검색을 한 후에는 해당 상태가 유지되어, 지도가 다른 위치로 움직여도 해당 필터링이 반영된 가이드카드만 보이는 기능을 구현하려고 한다.
하지만, 지도가 움직이면 해당 state가 유지되는 것이 아니라, 초기화되는 것을 확인하였다.

문제파악

useEffect(() => {
  kakao.maps.event.addListener(map, 'zoom_changed', kakaoEvent);
, []}
const kakaoEvent = () => {
  ... 생략
  latLngparams = { ...latLngparams, ...filterInfo };
  ... 생략
}

처음 접근했던 방식은 렌더링된 후 kakao.maps에 이벤트를 넣고, 해당 이벤트가 발생할 때마다, kakaoEvent 함수가 실행되게 하는 것이었다.
kakaoEvent가 실행되면 filterInfo는 필터링 값이 들어있는 객체이고, state인 filterInfo가 변경될 때마다 새로운 객체가 들어오게 되어, 해당 값이 반영된 가이드카드를 요청할 것이라고 예상하였다.

하지만 이벤트를 최초 등록했을 때 값인 fitlerInfo가 저장되어, 새로운 객체가 반영되지 않는 것이었다.

이를 해결하기 위해 useRef로 접근하였다.

문제해결

useRef는 값이 변경되어도 리렌더링이 발생하지 않기 때문에, 변경은 관리해야 하지만 리렌더링을 발생 시키지 않아도 되는 값을 다룰 때 사용한다.

리렌더링되지 않는 useRef
How to use State Variable (useState) in an EventHandler

(useRef()로 만든 변수는 컴포넌트의 생애주기를 통해 유지되지만, .current 프로퍼티의 값이 변경되어도 컴포넌트 리렌더링을 발생 시키지 않는다.)

또한 React 공식문서의 useRef와 관련된 설명을 보면, ref 객체를 반환한다.

이러한 특징을 이용하여, ref객체의 참조값을 사용하여, 다음과 같은 코드로 addEventListener 이벤트 발생 시 호출되는 함수 안의 값이 변경되는 값을 반영되도록 설정할 수 있는 것이다.

const filterRef = useRef();
filterRef.current = filterInfo;

...

latLngparams = { ...latLngparams, ...filterRef.current };

...

🍉 배포

S3 => ACL => 권한 제어 목록
로컬 서버에서 S3에 대한 접근 권한이 없어서 로컬 서버에서 S3에 접근이 안되었다.
IAM => 사용자 정의 => 정책권한 추가 => 키가 부여됨 => S3에 읽기, 쓰기 권한이 부여됨.

github 와 aws 연결해주는 것이 pipeline => codebuild로 와서 S3에 적용된다.
즉, codeBuild를 작성할 때 .env 파일을 직접 작성해주어야한다.

profile
start coding

0개의 댓글

관련 채용 정보