[Toy project] Lampang - 내 쿠팡 추천제품을 구매해보세요.

llama·2022년 12월 2일
3

토이프로젝트

목록 보기
5/5
post-thumbnail

Lampang

람팡은 쿠팡 파트너스* 기반의 어필리에이트 웹서비스 입니다.
※ 유저가 람팡을 통해 쿠팡의 상품을 구매하면 람팡은 상품 금액의 약 3~10%의 수수료를 정산 받을 수 있어요.

*쿠팡 파트너스 : 쿠팡에서 운영하는 온라인 제휴마케팅 서비스이며 홈페이지, 블로그, SNS 등을 사용하는 사람이라면 누구나 이용할 수 있어요. 쿠팡에서 판매되는 상품을 자신의 페이지에 노출하여 구매가 발생하면 광고비를 지급받을 수 있어요.


Userflow


Tech Stack

Frontend (My Role) : React, Recoil, React-query, React-beautiful-dnd, Mui

Backend : Express, PostgreSQL, Sequelize, Passport, Cheerio

Infrastructure : Vercel, Railway


Remarkable

Infinite Scroll (Intersection Observer + React-query)

Intersection Observer
초기에 scroll event에 throttle를 이용해 무한스크롤을 만들었는데, 300ms마다 불필요한 이벤트를 호출한다는 생각이 들었다.
이러한 문제를 좀더 세련되게 만들 방법이 없나 찾아보던 중 intersection observer를 알게 되었다.
해당 Web API는 루트 요소와 타겟 요소의 교차점을 관찰하여 교차시 비동기적으로 실행되고 reflow를 발생시키지 않는다는것을 알게되어 선택하게 되었다.


useInfiniteQuery (React-query)
API의 파라미터 값만 변경하여 아주 간단하게 동일한 API를 계속 호출할 수 있다.
해당 훅을 호출할 경우 data, hasNextPage, fetchNextPage() 등 무한 스크롤에 필요한 모든 정보가 반환되기 때문에
Intersection Observer와 찰떡궁합이라 선택하게 되었다.
🚨 cacheTime을 변경하지 않으면 캐시된 시간동안 다른페이지를 다녀올 경우 그전에 받아온 모든 페이지를 다시 fetch하는것에 유의해야한다.


Custom Hook
추후에도 무한 스크롤또는 레이지 로딩등을 이용할 경우, 손쉽게 재사용 할 수 있게 커스텀훅으로 만들어보았다.

Code
import { useEffect } from "react";

const useIntersectionObserver = ({
  root,
  target,
  onIntersect,
  threshold = 1.0,
  rootMargin = "0px",
  enabled = true,
}) => {
  useEffect(() => {
    if (!enabled) return;

    const observer = new IntersectionObserver(
      (entries) => (
        entries.forEach((entry) => entry.isIntersecting && onIntersect()),
        {
          // 루트가 없다면, 브라우저 뷰포트가 기본값으로 설정된다.
          root: root && root.current,
          rootMargin,
          threshold,
        }
      )
    );

    const currentTarget = target && target.current;

    if (!currentTarget) return;
    observer.observe(currentTarget);

    return () => observer.unobserve(currentTarget);
  }, [target, onIntersect, root, rootMargin, threshold, enabled]);
};

export default useIntersectionObserver;

Draggable List

문제
React-beautiful-dnd를 이용하여 Draggable List를 구현하였는데, React18버전에서 애니메이션이 동작하지 않는 문제가 발생했다.

원인
원인은 해당 라이브러리는 useLayoutEffect내부에서 droppable이 등록되는데 첫 componentDidMount에서는 실행되지만 컴포넌트가 다시 마운트될때는 실행되지 않아서 발생하는 문제였다.

해결
해당 문제는 React StrictMode를 제거하면 쉽게 해결 되긴하지만 올바른 방법같지는 않아서 다른방법을 찾아보았다.
검색해본 결과 requestAnimationFrame라는 WebAPI를 찾아볼 수 있었다.
requestAnimationFrame는 다음 리페인트 과정이 시작되기전 원하는 애니메이트를 만들어 줄 콜백이 실행되는 API인데, 이용한 결과 정상동작 하였다.
Link : Github Issue

Code
import { useEffect, useState } from "react";
import { Droppable, DroppableProps } from "react-beautiful-dnd";

const StrictModeDroppable = ({ children, ...props }: DroppableProps) => {
  const [enabled, setEnabled] = useState(false);

  useEffect(() => {
    const animation = requestAnimationFrame(() => setEnabled(true));

    return () => {
      cancelAnimationFrame(animation);
      setEnabled(false);
    };
  }, []);

  if (!enabled) {
    return null;
  }

  return <Droppable {...props}>{children}</Droppable>;
};

export default StrictModeDroppable;


Responsive Web


쿠팡 API 연동

HMAC : 해시 메시지 인증코드(Hash Message Authentication Code)의 준말로써 RFC2104 표준 암호화 프로토콜이다. 파트너스 API는 HMAC기반으로 제작되었으며 모든 request header의 Authorization에 생성한 HMAC signature를 함께 보내야한다.


📌한 줄 회고 (feat.작고 귀여운 나의 수익)

조그마한 수익이라도 낼 수 있는 프로젝트를 만들어보니 개발이 점점 더 흥미롭게 다가오는것 같다.

profile
요리사에서 프론트엔드 개발자를 준비하는중 입니다.

0개의 댓글