ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [원티드 프리온보딩 인턴십-프론트엔드] 3주차 회고록
    회고록 2023. 9. 9. 15:11

    3주차 회고록

    3주차는 1주차,2주차와 다르게 기능을 많이 요구하지는 않았지만 한가지 기능에 대해서 어떻게 구현하고 왜 이렇게 구현했는지에 대해서 기술하는 주차라고 생각한다.
    대부분의 조건은 이전과 동일하지만 큰 차이는 제공된 API 서버를 본인이 직접 호스팅하여 과제를 진행해야했고, 본인이 직접 API 서버를 배포시켜야 했다.

    과제를 진행하면서

    3주차는 과제를 진행하기에 앞서 나는 관심사를 분리하고 커스텀 훅을 적극적으로 사용하는 방식으로 프로젝트를 진행했다.

    기존에는 비슷한 기능을 하는 함수들을 모아 하나의 파일에 만들어 컴포넌트 단에서 함수를 호출하여 진행하는 방식으로 진행했으며 그로인하여 컴포넌트는 절차적인 형태의 코드가 많이 내포되어 있었다.

    또한 커스텀 훅을 기존에는 많이 어렵게 생각했다. 그래서 잘 사용하지 못하였다.

    하지만 3주차 수업을 통해서 횡단 관심사에 대해서 공부해보았고, 커스텀 훅과 의존성에 대해서 많이 생각해보게 되었다.

    그로인해 과제를 진행하면서 기존에는 그냥 주구절절히 작성하고 나중에 리팩토링 하는 과정을 거쳤다면 현재는 과제를 진행하기에 앞서 해당 로직이 어떤 인터페이스의 형태로 작성해야할까를 먼저 생각한뒤 이를 바탕으로 코드를 작성하였다.

    그렇기에 컴포넌트단에서는 특정한 함수에 값만 넘겨주면 그 로직이 어떻게 변하든지 동일한 값을 받는 형태로 변하였고, 그로인해 절차적이였던 코드는 선언적인 코드로 변하게 되었으며 추후에 리팩토링이나 내부의 로직을 수정할 때 외부의 상황을 생각하지 않고 오로지 해당 로직에만 집중해서 코드를 작성할 수 있었다.

    팀원들간에 회의를 진행할 때도 기존에는 내 코드를 설명하기 위해서 여러개의 파일을 왔다 갔다하며 설명하는데 어려움이 있었지만 선언적으로 변하게 되면서 오히려 코드를 설명할 때 설명하기도 쉽고 팀원들 또한 나의 코드를 이해하는데 드는 시간이 단축되었다.

    3주차는 정말 많은 정보를 배우게된 주차였고, 나의 실력도 향상되었다고 생각드는 주였다.

    배운점

    3주차의 핵심은 캐싱이였다.

    외부라이브러리를 사용하지 않고 어떻게 구현할 것이고, 캐싱을 expired을 구현하면 가산점을 주는 형태로 진행되었다.
    추가적으로 추천된 검색어를 키보드를 통해서 이동할 수 있어야만 했다.

    캐싱

    캐싱을 구현해야 한다는 것을 알고 바로 React-query의 Git을 방문하였다.

    나는 처음 배우는 기술이 있다면 해당 기술이 왜 등장하였고, 어떤 점을 개선하기 위해 나왔는지를 먼저 파악하고 내부 로직을 살펴보는 시간을 갖는다.
    (물론 모든 로직을 다 살펴보지는 않고 해당 코드의 핵심 기술들이 어떤 방식으로 돌아가는지를 가늠해보기 위해서이다.)

    그렇게 캐싱 기술을 구현하기 위해 첫날에는 캐싱에 대한 지식을 배우기 위해서 React-query의 홈페이지와 Example코드를 보고, 이후에는 MDN을 방문하여 해당 기술을 구현하기 위한 API들을 찾아보았다.

    그리고 나는 Cache API에 대해서 알게되었다. 해당 API는 브라우저에서 제공하는 자체 API로 캐싱을 위한 도와주는 메서드들이 포함되어 있다.
    (링크)

    Cache API를 사용하면 해당 데이터는 브라우저의 Cache Storage에 저장되어진다.

    // cache.put()
    fetch(url).then((response) => {
      if (!response.ok) {
        throw new TypeError("bad response status");
      }
      return cache.put(url, response);
    });

    사용법은 매우 간하였다. 응답을 받으면 cache.put()만 해주면 된다.

    하지만 나의 경우에는 Axios를 사용하면서 진행했기 때문에 응답도 AxiosResponse의 형태로 받아왔다. 그래서 Cache를 제대로 저장하지 못하는 현상이 있었기에 이를 fetch형태의 Response형태로 바꿔주는 과정도 필요했다.

    이렇게 응답을 Cache Storage에 저장하였다면 제거도 진행할 수 있다.

    caches.open("v1").then((cache) => {
      cache.delete("/images/image.png").then((response) => {
        someUIUpdateFunction();
      });
    });

    제거(match도 동일하다)의 경우에는 then 속에 then을 사용하기 때문에 then의 depth만 실수하지 않는다면 틀릴일이 없다.

    이처럼 Cache API를 사용하면 캐시를 관리하는 것이 가능해진다.

    캐싱 전략

    내가 세운 캐싱전략은 아래와 같다.

    • 캐싱된 데이터가 없다면 응답 데이터를 캐싱해줘야 한다. (Create)
    • 응답의 주소를 바탕으로 Cache Storage에 캐싱된 데이터가 있는지 확인해줘야 한다. (Read)
    • 캐싱된 데이터가 Stale하지 않다면 데이터를 다시 받아와 기존에 캐싱된 데이터를 수정해줘야 한다. (Update)
      (https://www.youtube.com/live/MArE6Hy371c?si=a2DseWxqzKmT752Z&t=4397)
    • 캐싱된 데이터가 불필요하다고 판단되면 이를 Cache Storage에서 삭제해줘야 한다. (Delete)

    전략을 이렇게 세운후에 코드를 진행하는데 기존처럼 함수형으로 진행했다면 구조가 복잡해지고 코드가 난잡해질것 같다고 생각을 해, 처음부터 Class를 생성하여 진행하였다.

    그로인해 기능을 추가해야하거나 수정해야 하는 경우에는 외부코드를 생각하지 않고 로직만 생각하며 코드를 다시 작성할 수 있었고, 이를 사용하는 로직에서도 단순히 호출하고 값만 넘겨주면되니 생산성 면에서 더 증가하였다.

    키보드 이벤트

    검색창에 값을 입력하였을 때 키보드로 해당 추천된 검색어를 이동할 수 있게 구현할 수 있어야 했다.

    나는 이 요구사항을 해결하기 위해 키보드 이벤트를 도입했고, 큰 문제없이 추천된 검색어 이동을 구현했다.

    하지만 키보드로 선택되어지는 리스트 아이템에 초점을 맞춰 해당 아이템이 보여지게 계속해서 스크롤을 이동시켜줘야 했다.
    EX) 50개 아이템으로 리스트가 이루어져 있고, 화면에 보여지는 아이템은 10개(110개의 아이템)이다. 내가 키보드로 110개의 아이템을 이동하고 11번째 아이템에 포커스를 맞추면 리스트는 2번째 아이템부터 11번째 아이템을 보여줘야 한다.

    나는 어떻게 스크롤을 이동시키지에 대해서 계속해서 고민했는데 팀원이 이를 해결할 수 있는 제안을 했다.

    바로 scrollIntoView였다. 나는 해당 기술에 대해서 당연히 알고 있었고, 사용도 해보았는데 여기서 이 기술을 쓸 생각을 하지 못했다.

    하지만 scrollIntoView의 경우에는 직접적으로 Dom을 조작해야만 했기 때문에 추가적인 사전작업이 필요하다.

    우선 ul태그안에 li태그에 접근해야 하기 접근하기 위한 방법은 여러가지가 있었다.

    1. li태그에 고유한 Id값을 부여해 document.getElementById로 접근
    2. ref를 통해 DOM 요소에 접근

    팀원이 제시한 1번의 경우에는 리액트가 제시하는 방향에 맞지 않는 방법이다. 리액트의 경우에는 직접적인 Dom조작을 권장하지 않기 때문에 해당 방법은 사용하지 않았다. 그래서 나는 2번의 방법을 통해 Dom 요소에 접근하기로 결정을 하였다.

    그럼 2번의 방법을 통해서 Dom에 접근을 하는데 어디에 ref를 걸어줄 것인지를 고려해야 한다.

    일단 내가 접근해야하는 요소는 li태그이다. 그렇다고 li태그에 동적으로 모두 ref를 달아주는 것은 불가능하고 가능하다 하더라도 매우 많은 ref가 생성되기 때문에 이 방법은 선택하지 않았다.

    그래서 나는 ulref를 통해 접근하여 element.childElement를 통해 접근하였다. 이렇게 접근함으로 써 리액트에서 제시하는 방향을 어기지 않고, 동적으로 생성되는 하위 요소에 모두 접근하는 것이 가능해다.

    const Target_Li = ref.current.childElement();
    changeFocusTarget(Target_Li(index));

    3주차를 마무리하면서

    3주차는 내가 프로젝트를 진행할 때 코드를 작성하는 스타일에 대해서 큰 변화가 있었던 한주라고 생각한다.

    캐싱에 대해서 직접 구현하고 사용해보았기 때문에 최근에 많이 사용되는 React-query를 사용하면서 캐싱을 구현하면서 겪은 문제점과 고려해야할 점을 해당 라이브러리에서는 어떻게 이러한 문제를 해결했는지에 대해 이해하고 사용하기 때문에 보다 빠르게 배우고 사용할 수 있을것 같다.

    그리고 기본적으로 제공되는 Web API를 다양한 방법에서 접근하고 사용해보는 시간이였다.

Designed by Tistory.