[React] React-Query 사용 이유 & Queries 개념편

조예진·2022년 7월 17일
35
post-thumbnail

📝 들어가기 전

회사에서 커스텀 훅 기반으로 React 프로젝트를 다시 구축하게 되면서
React-Query 라이브러리도 사용하게 되었다.
그래서 React-Query에 대해 한번 깊게 파보기 위해 차근차근 포스팅해보려고 한다.

우선, 공식문서 토대로 번역해서 요약한 거라 의역이 조금 많이 되어 있어
혹시라도 추가해야하거나 부족한 부분이 있다면 댓글로 마구마구 피드백 감사드립니다:)


React-Query란?

☞ React Query는 데이터 Fetching, 캐싱, 동기화, 서버 쪽 데이터 업데이트 등을 쉽게 만들어 주는 React 라이브러리이다.

React-Query가 만들어진 이유

✅ 서버 쪽의 데이터들을 좀더 쉽게 관리하기 위해

✔️ 기존에 Redux, Mobx, Recoil과 같은 다양하고 훌륭한 상태 관리 라이브러리들이 있긴 하지만, 클라이언트 쪽의 데이터들을 관리하기에 적합할 순 있어도 서버 쪽의 데이터들을 관리하기에는 적합하지 않은 점들이 있다.

이 점을 해결하기 위해 React-Query가 만들어졌다.

React-Query의 장점

✔️ 위에서 설명한 것처럼 React 어플리케이션 내에서 데이터 패칭, 캐싱, 동기적, 그리고 서버의 상태의 업데이트를 좀 더 용이하기 위해 만들어준다.

✔️ 기존에는 직접 만들어서 사용했던 기능들을 별도의 옵션으로 지원하여 복잡하고 이해할 수 없는 수많은 코드를 대신 React-Query 로직을 통해 짧은 코드로 대체할 수 있게 되었다.

✔️ 프로젝트 구조가 기존보다 단순해져 애플리케이션을 유지 보수하기 쉽고, 새로운 기능을 쉽게 구축할 수 있다.

그 외에도 많은 장점이 있다.

→ React Query는 별도의 설정 없이 즉시 사용 가능하다

→ 캐싱을 효율적으로 관리해준다

→ 같은 데이터에 대한 여러번의 요청이 있을 시 중복을 제거한다.

→ 백그라운드에서 알아서 오래된 데이터를 업데이트해준다.

→ 데이터 업데이트 시 최대한 빨리 반영한다.

→ 페이징처리, 지연 로딩 데이터와 같은 성능 최적화해준다

→ 서버 쪽 데이터를 가비지 컬렉션을 이용하여 자동으로 메모리를 관리해준다.

→ 구조적 공유를 통해 쿼리의 결과를 기억해준다.


React-Query 간단하게 맛보기

import {
   useQuery,
   useMutation,
   useQueryClient,
   QueryClient,
   QueryClientProvider,
 } from 'react-query'

import { getTodos, postTodo } from '../my-api'

//먼저 client를 만들어준다.
const queryClient = new QueryClient()

function App() {
	return (
		// 애플리케이션에 클라이언트를 제공한다.
		<QueryClientProvider client={queryClient}>
			<Todos />
		</QueryClientProvider>
	)
}

function Todos() {

	// client에 접근하기
	const queryClient = useQueryClient()

	// Queries (데이터 패칭하기 위한 hook)
	const query = useQuery('todos', getTodos)

	// Mutation
	const mutation = useMutation(postTodo, {
		onSuccess: () => {
				// todos 라는 unique key에 대한 기존 데이터를 무효화하고 다시 가져오기
				queryClient.invalidateQuries('todos')
		},
		})
	})
	return (
	<div>
       <ul>
		// useQuery로 가져온 데이터는 아래와 같이 query.data로 꺼내올 수 있다.
         {query.data.map(todo => (
           <li key={todo.id}>{todo.title}</li>
         ))}
       </ul>
 
       <button
         onClick={() => {
			// 데이터 변경하기
           mutation.mutate({
             id: Date.now(),
             title: 'Do Laundry',
           })
         }}
       >
         Add Todo
       </button>
     </div>
)
}

React-query 깊게 파보기

❇️ useQuery, useMutation 등 React-query에서 제공하는 hook에는 정말 다양하고 개발자들을 편리하게 해주는 옵션들이 많다!

이번편에서는 그 중 Queries 관련한 내용에 대해서 자세히 다뤄볼 예정이다.

다음 포스팅에서는 Mutation내용으로 이어나갈 예정이다


📍  Queries

Query Basic

✅ 사용법

import { useQuery } from 'react-query'
 
 function App() {
   const info = useQuery('todos', fetchTodoList)
 }

✅ Query는 GET, POST 메소드 포함을 기반으로 서버에서 데이터를 패칭하기 위한 비동기 함수와 사용된다.

✅ 'todos': 첫번째 인자로, unique key를 명시해준다.
✔️ 해당 key는 내부적으로 데이터 재요청, 캐싱, 쿼리를 공유하기 위해 사용된다.

✅  fetchTodoList: 두번째 인자에는 우리가 요청할 비동기 함수를 넣어주는데, 데이터와 error를 return해준다.

✅  useQuery return값에 포함되어 있는 states

  • 주요 states
    - isLoading or status === 'loading' : 현재 데이터를 요청 중이나 아직 데이터가 없을 경우
    - isError or status === 'error': 쿼리에서 에러가 났을 경우
    error : 해당 property로 에러 메세지를 확인할 수 있다.
    - isSuccess or status === 'success' - 쿼리 요청 성공
    data : 해당 property로 성공한 데이터를 확인할 수 있다.
    - isIdle or status === 'idle': 이 쿼리는 현재 사용할 수 없을 때 나옴
    - isFetching : 데이터 요청 중일 때는 (내부적으로 리패칭 중 일때도 포함) 항상 True를 리턴한다
  • 사용방법
    - 방법 1. boolean 타입으로 체크하기
       function Todos() {
       const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)
        
        if (isLoading) {
          return <span>Loading...</span>
        }
       
        if (isError) {
          return <span>Error: {error.message}</span>
        }
       
        // We can assume by this point that `isSuccess === true`
        return (
          <ul>
            {data.map(todo => (
              <li key={todo.id}>{todo.title}</li>
            ))}
          </ul>
        )
       }
    • 방법 2. status 하나로 꺼내서 사용할 수도 있음
      function Todos() {
         const { status, data, error } = useQuery('todos', fetchTodoList)
       
         if (status === 'loading') {
           return <span>Loading...</span>
         }
       
         if (status === 'error') {
           return <span>Error: {error.message}</span>
         }
       
         // also status === 'success', but "else" logic works, too
         return (
           <ul>
             {data.map(todo => (
               <li key={todo.id}>{todo.title}</li>
             ))}
           </ul>
         )
       }

📍 Query Keys

✅ React Query는 query key로 캐싱을 관리한다.

✅ 간단한 문자열이어도 되고, 배열 형태, 중첩된 객체와 같이 복잡하든 상관없다

✅ Query key가 순차적 진행을 보장하는 직렬화 기법으로 쿼리의 데이터는 유일하다.

✔️ Query key가 문자열일 때

// A list of todos
 useQuery('todos', ...) // queryKey === ['todos']
 
 // Something else, whatever!
 useQuery('somethingSpecial', ...) // queryKey === ['somethingSpecial']

✔️ Query key가 배열일 때

// An individual todo
 useQuery(['todo', 5], ...)
 // queryKey === ['todo', 5]
 
 // An individual todo in a "preview" format
 useQuery(['todo', 5, { preview: true }], ...)
 // queryKey === ['todo', 5, { preview: true }]
 
 // A list of todos that are "done"
 useQuery(['todos', { type: 'done' }], ...)
 // queryKey === ['todos', { type: 'done' }]

✔️ Query key에 있는 object들의 순서는 중요하지 않다.

동일한 Query key -> array의 object내 에 있는 값들의 순서는 중요하지 않음 (동일함)
useQuery(['todos', { status, page }], ...)
useQuery(['todos', { page, status }], ...)
useQuery(['todos', { page, status, other: undefined }], ...)
동일 하지 않은 Query key. -> array 값의 순서는 중요하다
useQuery(['todos', status, page], ...)
useQuery(['todos', page, status], ...)
useQuery(['todos', undefined, page, status], ...)

✔️ Query key는 파라미터를 사용해도 된다.

파라미터가 unique한 값이라면 인자로 받아 아래와 같이 사용할 수 있다.

function Todos({ todoId }) {
   const result = useQuery(['todos', todoId], () => fetchTodoById(todoId))
 }

📍Query Functions

✅ Query Function은 promise를 return하는 함수

✅ Promise는 data를 return하거나 에러가 나면 에러를 return한다.

아래와 같이 function을 작성할 수 있다.

useQuery(['todos'], fetchAllTodos)
useQuery(['todos', todoId], () => fetchTodoById(todoId))
useQuery(['todos', todoId], async () => {
   const data = await fetchTodoById(todoId)
   return data
 })
useQuery(['todos', todoId], ({ queryKey }) => fetchTodoById(queryKey[1]))

✅ Query Function에서 발생된 에러는 query의 error state에 남는다.

const { error } = useQuery(['todos', todoId], async () => {
   if (somethingGoesWrong) {
     throw new Error('Oh no!')
   }
 
   return data
 })

✅ fetch와 같이 기본적으로 Http 요청 실패에 대한 에러를 제공하지 않는 경우 아래와 같이 직접 error를 던져줘야한다.

✔️ axios와 graphql-request과 같은 대부분의 함수가 기본적으로 HTTP 요청이 실패하면 에러를 반환하지만,

fetch와 같이 몇몇 함수는 오직 network error에 대해서만 에러를 내뱉는 경우가 있다.

이 경우에 아래와 같은 방법으로 에러를 직접 반환해줘야한다.


useQuery(['todos', todoId], async () => {
   const response = await fetch('/todos/' + todoId)
   if (!response.ok) {
     throw new Error('Network response was not ok')
   }
   return response.json()
 })

📝  fetch 공식문서 발췌

[fetch()](https://developer.mozilla.org/en-US/docs/Web/API/fetch) promise only rejects when a network error is encountered (which is usually when there's a permissions issue or similar). A [fetch()](https://developer.mozilla.org/en-US/docs/Web/API/fetch) promise does not reject on HTTP errors (404
, etc.).

✅ Query Function Variables

Query keys는 데이터를 요청하는동안 식별한는 것 뿐만아니라 또한 필요할 때 편리하게 Query Function에서 사용도 할 수 있다.

이렇게 하면, 필요할 때마다 아래와 같이 Query Function 에서 추출해서 사용할 수 있다.

function Todos({ status, page }) {
   const result = useQuery(['todos', { status, page }], fetchTodoList)
 }
 
 // Access the key, status and page variables in your query function!
 function fetchTodoList({ queryKey }) {
   const [_key, { status, page }] = queryKey
   return new Promise()
 }

✅ 여러개의 인자가 아니라 객체 하나로도 사용할 수 있다.

import { useQuery } from 'react-query'
 
 useQuery({
   queryKey: ['todo', 7],
   queryFn: fetchTodo,
   ...config,
 })

📍Parallel Queries : **useQueries**

✅ 여러개의 useQuery를 나란히 사용할 수 있다.

→ 아래와 같이 사용할 시 다른 쿼리가 실행되기 전에 첫번째 쿼리가 중단하고 에러를 반환할 수 있다.

function App () {
   // The following queries will execute in parallel
   const usersQuery = useQuery('users', fetchUsers)
   const teamsQuery = useQuery('teams', fetchTeams)
   const projectsQuery = useQuery('projects', fetchProjects)
   ...
 }

✔️ 그럴땐 , **useQueries hook을 사용할 수 있다.

useQueries는 Query Option 객체를 배열로 받을 수 있고, 마찬가지로 결과값 또한 배열로 return 해준다.

function App({ users }) {
   const userQueries = useQueries(
     users.map(user => {
       return {
         queryKey: ['user', user.id],
         queryFn: () => fetchUserById(user.id),
       }
     })
   )
 }

📍 Dependent Queries: 동기적으로 사용하기

✅ enabled: true이면 특정 조건이 trued 때만 실행하겠다

→ 이전 함수가 끝나고 다음 것이 영향을 받을 때 enabled option을 사용하면 좋다.

const { data: user } = useQuery(['user', email], getUserByEmail)
 
 const userId = user?.id
 
 // Then get the user's projects
 const { isIdle, data: projects } = useQuery(
   ['projects', userId],
   getProjectsByUser,
   {
     // The query will not execute until the userId exists
     enabled: !!userId, 
   }
 )

📍 Loading state 전역으로 사용하기

✅ useIsFetching

→  useQuery 내부 isLoading state 말고 backgroud에서의 fetching 체크가능하다

import { useIsFetching } from 'react-query'
 
 function GlobalLoadingIndicator() {
   const isFetching = useIsFetching()
 
   return isFetching ? (
     <div>Queries are fetching in the background...</div>
   ) : null
 }

--

profile
블로그 이전 중 -> https://devjooj.tistory.com/

3개의 댓글

comment-user-thumbnail
2023년 2월 7일

정리가 깔끔해서 이해하기 좋았습니다
좋은글 감사합니다!

답글 달기
comment-user-thumbnail
2024년 8월 17일

Conquer NURS FPX 4060 Assessment with Comprehensive Online Tutoring

Introduction to NURS FPX 4060 Series Assessment
The NURS FPX 4060 series is a pivotal component of your nursing education, focusing on the integration of public health concepts into nursing practice. Covering NURS FPX 4060 Assessment 1 https://experttutors.info/nurs-fpx-4060-assessment-1/ through NURS FPX 4060 Assessment 4, this series empowers you to address public health challenges effectively and contribute to the wellbeing of communities.

Tailored Tutoring for Exceptional Results
Our tutoring service is specifically designed to navigate the complexities of the NURS FPX 4060 assessments. Whether you're grappling with the nuances of NURS FPX 4060 Assessment 2 or the comprehensive requirements of NURS FPX 4060 Assessment 3, our personalized tutoring plans are crafted to fit your learning style and academic goals.

Personalized Learning Journeys
Recognizing that each student has unique learning needs, our approach is to offer personalized tutoring that directly addresses your areas of focus. This includes targeted preparation for NURS FPX 4060 Assessment 4, ensuring that you're well-equipped to tackle each aspect of the assessment with confidence.

Expertise in Public Health Nursing
Our tutors are seasoned professionals with extensive experience in public health nursing. They bring a wealth of practical knowledge and theoretical understanding to help you excel in NURS FPX 4060 Assessment 1 and beyond, providing insights into effective public health strategies and interventions.

Accelerate Your Learning and Career
We aim to streamline your path through the NURS FPX 4060 series, enabling you to complete your assessments efficiently and with a deep understanding of public health nursing. With focused support for NURS FPX 4060 Assessment 2 and NURS FPX 4060 Assessment 3, we help you fast-track your academic and professional development.

Comprehensive Support for Academic Excellence
Our services extend beyond tutoring to include "Write my assessment" and "Online assessment help," ensuring that you have access to comprehensive resources for NURS FPX 4060 Assessment 4 and all other assessments in the series. Our aim is to support your journey towards becoming a public health nursing leader.

Your Gateway to Advanced Public Health Nursing
Opting for our NURS FPX 4060 tutoring services marks the beginning of your successful journey in public health nursing. With our tailored tutoring, expert guidance, and extensive resources, you're set to achieve excellence in your assessments and make a significant impact in the field of public health nursing.
Advance your nursing career with our specialized NURS FPX 4060 assessment tutoring. Contact us today to see how we can help you excel in public health nursing and beyond.

답글 달기
comment-user-thumbnail
2024년 8월 17일

Expert Tutors NURS FPX 4900 Assessment: Your Path to Nursing Leadership

Unlock your leadership potential in nursing with our targeted NURS FPX 4900 assessment tutoring. From Assessment 1 to 5, our expert guidance is designed to ensure your success and propel your career forward.

Introduction to NURS FPX 4900 Series Assessment
The NURS FPX 4900 series is the cornerstone of your development as a nursing leader, focusing on the synthesis of your learning to tackle complex healthcare issues. This comprehensive assessment series, from NURS FPX 4900 Assessment 1 to NURS FPX 4900 Assessment 5, is designed to evaluate your readiness to lead in the dynamic field of nursing.

Specialized Tutoring for Nursing Leaders
Our tutoring services are specifically crafted to support your journey through the NURS FPX 4900 series. Whether it's the critical analysis required in NURS FPX 4900 Assessment 2 or the strategic planning involved in NURS FPX 4900 Assessment 3 https://experttutors.info/nurs-fpx4900-assessment-3/ , our personalized tutoring plans are tailored to meet the demands of each assessment.

Customized Learning for Future Leaders
We recognize the importance of individualized learning pathways in developing leadership skills. Our approach includes personalized tutoring that focuses on your unique strengths and areas for improvement, ensuring that you are well-prepared for NURS FPX 4900 Assessment 4 and the culminating NURS FPX 4900 Assessment 5.

Expert Guidance from Seasoned Nursing Leaders
Our team of tutors includes experienced nursing leaders who bring a wealth of knowledge and real-world experience to their teaching. With their guidance, you'll gain insights into effective leadership and management strategies, enhancing your performance in NURS FPX 4900 Assessment 1 and beyond.

Accelerate Your Path to Nursing Leadership
Our goal is to facilitate your successful completion of the NURS FPX 4900 series, enabling you to advance in your career as a nursing leader. With focused support for NURS FPX 4900 Assessment 2 and NURS FPX 4900 Assessment 3, among others, we aim to streamline your academic journey without compromising the depth of learning.

Comprehensive Support for Aspiring Leaders
Beyond tutoring, we offer a range of services including "Write my assessment" and "Online assessment help," designed to prepare you comprehensively for NURS FPX 4900 Assessment 4 and NURS FPX 4900 Assessment 5. Our support extends to all facets of the assessment series, ensuring you are ready to lead and innovate in the nursing profession.

Begin Your Leadership Journey with Confidence
Choosing our tutoring services for the NURS FPX 4900 series is a decisive step towards achieving your goals as a nursing leader. With personalized support, expert guidance, and a focus on leadership development, you are poised to excel in your assessments and make a significant impact in healthcare.
Elevate your nursing career with our expert NURS FPX 4900 assessment tutoring. Contact us today to learn how we can help you become a transformative leader in the nursing field.

답글 달기