React Query - 데이터 변환(filtering)

박정호·2023년 1월 14일
0

React Query

목록 보기
8/14
post-thumbnail

🚀 Start

어느 프로젝트를 보든 대부분 포함되어있는 기능 중 하나가 아마 필터링 기능이지 않을까 싶다.

이전에 내가 필터링 기능을 구현할 때는 클라이언트단에서 서버로부터 받은 데이터를 가지고 필터링을 해주거나, 프론트엔드에서 원하는 데이터만 요청시 서버단에서 그에 대한 필터링된 데이터만 응답해주는 방법이었다.

이번엔 useQuery의 Select 옵션을 사용해보자.

select 옵션을 사용하면 쿼리함수가 반환하는 데이터를 변환시킬 수 있다.



👍 Select option in RQ

React Query는 Memoization을 통해 불필요한 연산을 줄이는 최적화를 해준다.

💡 메모이제이션 : 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술

React Query는 Select 함수를 삼중 등호로 비교하며, Select 함수는 데이터와 함수가 모두 변경되었을 경우에만 실행된다.

마지막으로 검색한 데이터와 동일한 데이터이고 Select 함수에도 변동이 없으면 Select함수를 재실행하지 않는 것이 React Query의 최적화라고 할 수 있다.

따라서 Select함수에는 안정적인 함수가 필요하고, 메모이제이션하는 React의 useCallback을 사용하면 된다.

💡 매우좋은 글 👉 React Query Data Transformations



⭐️ Select

간단한 예를 통해 알아보자.

select 기능을 통해서 내가 원하는 카테고리를 클릭시 해당 카테고리에 포함되는 데이터만 출력되게 만들 것이다.


1️⃣ filter의 상태값이 all이라면.

  • 즉, 아무 filtering이 작동되지 않은 전체데이터를 보여주는 경우에는 아무런 데이터를 반환하지 않아도 됨으로 undefined.

2️⃣ filter의 상태값이 all이 아니라면.

  • 즉, filtering 기능이 동작한다면 selectFn 함수가 실행되고, 이때 인자로 useQuery로 받은 데이터와 filter 상태값이 전달된다.

  • useCallback을 사용하여 Select 함수에 변동이 없으면 Select함수를 재실행하지 않게 만들어 최적화.

// useStaff.tsx (커스텀훅)
export const useStaff = (): UseStaff => {
  const [filter, setFilter] = useState('all');

  const selectFn = useCallback( // 2️⃣ 번
    (unfilterdStaff) => filterByTreatment(unfilterdStaff, filter),
    [filter],
  );

  const { data: staff } = useQuery(queryKey, queryFn, {
    select: filter !== 'all' ? selectFn : undefined, // 1️⃣ 번
  });

  return { staff, filter, setFilter };
}

3️⃣ filterByTreatment은 인자로 받은 데이터를 원하는 카테고리에 맞게 출력되게끔 동작하는 필터링 함수.

  • staff : 전달받은 전체 데이터
  • treatmentName : 전달 받은 데이터 속 데이터의 종류
    • 전달받은 treatmentName의 종류에 따라 출력되는 데이터가 변경된다.
    • 예를들어, treatmentName으로 Massage가 오면 Massage만 하는 staff 데이터가 출력되고, Scrub이 오면 Scrub만 하는 staff 데이터가 온다.
// util.tsx (필터링함수)
export const filterByTreatment = (staff, treatmentName) => {
  return staff.filter((person) =>
    person.treatmentNames
      .map((t) => t.toLowerCase())
      .includes(treatmentName.toLowerCase()),
  );
}

4️⃣ 데이터 종류가 변경되는 원리는 실제로 화면에 보이는 컴포넌트에서 Radio태그를 통해 카테고리를 클릭할 경우 클릭한 값에 따라 변경되는 것이다.


5️⃣ Radio태그에 출력될 값은 filter, 클릭시 실행되는 값은 setFilter.

  • 따라서, 위에서 실행된 유틸함수에 전달된 filter값이 클릭에 따라 변경되는 것.
// AllStaff.tsx (화면에 출력되는 컴포넌트)
export const AllStaff = () =>  {
  const { staff, filter, setFilter } = useStaff();
  const treatments = useTreatments();

  return (    
      <RadioGroup onChange={setFilter} value={filter}> // 5️⃣ 번
          <Radio value="all">All</Radio>
          {treatments.map((t) => (
            <Radio key={t.id} value={t.name}>
              {t.name}
            </Radio>
          ))}
      </RadioGroup>
  );
}

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)

0개의 댓글