Santos의 개발블로그

[React-query] 데이터 filtering 하기 본문

NPM/Valuable

[React-query] 데이터 filtering 하기

Santos 2024. 3. 2. 21:35

* 이 글은 filtering data in react query like a pro 번역하였습니다.

 

Filtering Data in React Query Like a Pro

In this article, we will explore a few tricks to filter and normalize data in React Query in the most efficient way I know

betterprogramming.pub

Motivation

이 글은 오랫동안 배우고 사용했던 Tool, React-query를 통해 data를 filtering과 normalizing 하는 것에 대한 글입니다. 

Data를 filtering과 normalizing 하는 것은 대부분의 웹 어플리케이션에서 필수적인 부분입니다. 쉽게 접근할 수도 있지만 반대로 확장 가능한 방법을 고려하게 되면 까다로운 부분이기도 합니다. React-query를 사용하는 어플리케이션은 해당 부분에 속하지만, 그래도 까다로운 부분을 React-query에서 처리해줍니다.

Preliminary resources

이 글은 React-query를 어느 정도 알고 있는 독자에게 적합할 것 같습니다. 만약 그렇지 않다면 React-query 기초에 대한 아래의 글을 읽어보세요. 또한 공식문서, 아래의 블로그를 참고해보세요.

 

7 Tips for Using React Query in Large Projects

Callbacks for side effects, manually invalidate cache data, and more

betterprogramming.pub

 

 

Overview

Overview React Query is often described as the missing data-fetching library for React, but in more technical terms, it makes fetching, caching, synchronizing and updating server state in your React applications a breeze. Motivation Out of the box, React a

react-query.tanstack.com

 

 

TkDodo's blog

A technical blog about frontend-development, TypeScript and React

tkdodo.eu

Filtering data on the Server

Problem statement

직원들의 인사 데이터 배열 형식으로 서버에서 응답을 받았다라고 가정해봅시다. 이 API는 두개의 query param을 갖고있습니다. 첫 번째는 position이고 두 번째는 name 입니다. 이 API는 요청되는 query param에 따라 데이터를 필터링 해줍니다. 그리고 param이 없다면 직원들의 전체 데이터를 응답해줍니다. 

// GET /api/v1/employees?positions=:positions&name=:name

// Response without applying filters
[{
  name: 'Michael Scott',
  birthdate: '1975-02-28',
  position: 'regional_manager',
  yearly_salary: 100000,
  active: true
},
{
  name: 'Dwight Kurt Schrute',
  birthdate: '1980-02-12',
  position: 'assistant_to_regional_manager',
  yearly_salary: 70000,
  active: true
},
{
  name: 'James Halpert',
  birthdate: '1982-04-02',
  position: 'salesman',
  yearly_salary: 70000,
  active: true
},
{
  name: 'Phyllis Vance',
  birthdate: '1975-07-18',
  position: 'salesman',
  yearly_salary: 65000,
  active: true
}];

만약 직원들 중 postion이 sales 인 데이터만을 받고 싶다면 GET /api/v1emplyees?positions=sales, 라고 요청을 하면 되겠죠. 브라우저에서 유저의 선택에 따라 요청된 데이터는 react에 dom에 의하여 UI를 재구성 할 것입니다. 

 

The solution

자동으로 처리될 수 있는 이러한 기능을 만들기 위해서는 React-query에서 제공하는 refetch를 사용하면 됩니다. 

 

알다시피 React-query는 query-key를 사용하여 cash된 데이터를 API로부터 fetch 합니다. 

export const useGetEmployees = () => {
  return useQuery(['employees'],  () => fetchEmployees());
};

const SomeComponent = () => {
  const { data } = useGetEmployees();
}

Query-key가 update 될 때 refetch할 data는 자동으로 Trigger 됩니다. 그렇기 때문에 query-key에 이미 필터된 데이터를 추가하여 해당 기능을 활용할 수 있습니다. 필터된 데이터가 update되면 자동으로 API가 호출되고, 필터된 데이터를 다시 서버로부터 받아볼 수 있습니다. 

export const useGetEmployees = (filters) => {
  // Everytime your filters change, react´query will refetch data, if your filters don't change, your data will remain
  // cached avoiding API requests.
  return useQuery(['employees', filters],  () => fetchEmployees(filters));
};

const SomeComponent = () => {
  const [filters, setFilters] = useState({});
  const { data } = useGetEmployees(filters);

  const onChange = (value) => {
    setFilters(value)
  }

  // Some fancy UI that calls onChange function upon filter selection in the UI
}

Query-key 법에 주목해보세요. 일부로 저장된 필터의 값이 update된다면 해당 function이 호출될 것이고, 그렇지 않다면 호출되지 않을 것입니다. 

Filtering data on the Client

Problem statement

위와 같은 상황에서 만약 데이터가 필터링 되지 않은채로 응답을 받았다고 가정해보자. 이럴 때 Client에서 필터링을 해야하는데, 최소한의 API 요청을 유지하고, 더 나은 퍼포먼스를 낼 수 있는 기능을 만들기 위해서는 어떻게 해야 할까요? 

 

The solution, selectors 

 Selctors 는 많이 알려져 있지는 않지만, React-query에서 매우 유용한 기능입니다. cached된 데이터가 관련없이 filter된 데이터를 전송할 수 있습니다. 따라서 selector를 query hooks에 연결하고, 요소에서 선택한 필터를 기반으로 필터링을 수행할 수 있습니다. 

export const useGetEmployees = (filters) => {
  // Notice we only use `employees` as query key, because we want to preserve our cache
  return useQuery(
    ['employees'],
    () => fetchEmployees(filters),
    // We pass a third argument to our useQuery function, an options object
    {
      select: (employees) => employees.filter((employee) => employee.name.includes(filters.name) ),
    }
  );
};

const SomeComponent = () => {
  const [filters, setFilters] = useState({});
  const { data } = useGetEmployees(filters);

  const onChange = (value) => {
    setFilters(value)
  }

  // Some fancy UI that calls onChange function upon filter selection in the UI
}

 userQuery의 세번째 인자 값으로 전달된 selector를 주목해 보세요. 해당 객체는 useQuery의 옵션으로 귀속 되어 있습니다. select 속성을 이용하여 selector 함수를 전달 할 수 있습니다. 

 

select 함수는 데이터 filtering과 normalization을 할 수 있습니다. 이는 API 요청에 따라 trigger 되지 않습니다.

Conclusion

React-query에서 filtering은 단순하게 처리할 수 있습니다. 여기서 중요한 점은 필터링이 client에서 수행이 되는지 server에서 수행되는지에 대한 여부를 함께 작업하는 팀과 조정하는 것입니다. 이 글을 통해 확장가능한 방법까지 고려하여 적절한 전략을 적용하기기 바랍니다. 


< 참고자료 >

 

[사이트] #medium

https://medium.com/better-programming/filtering-data-in-react-query-like-a-pro-ec481b53b515

 

Filtering Data in React Query Like a Pro

In this article, we will explore a few tricks to filter and normalize data in React Query in the most efficient way I know

betterprogramming.pub

Filtering data in React query like pro end

'NPM > Valuable' 카테고리의 다른 글

Axios 뜯어보기  (2) 2023.11.30
Recoil  (0) 2023.11.04
cookie  (0) 2020.12.26
cookie-parser  (0) 2020.08.01
axios  (0) 2020.07.26
Comments