상태 관리 React-Query

sun·2024년 4월 11일
0

javascript & react

목록 보기
17/22

상태란 주어진 시간에 대해 시스템을 나타내는 것으로 언제든지 변경될 수 있음.
즉 문자열, 배열 객체 등의 형태로 응용 프로그램에 저장된 데이터

  • 개발자 입장에서 관리해야하는 데이터들

상태관리는?

사앹를 관리하는 방법에 대한 것
프로덕트가 커짐에 따라 어려움도 커짐
상태들은 시간에 따라 변화함
React에서는 단방향 바인딩이므로 Props Driling 이슈도 존재
Redux와 MobX 같은 라이브러리를 활용해 해결하기도 함.

상태를 두가지로 나누어 보자면

Client StateServer State
Key Point는 데이터의 Ownership이 있는 곳

  • 데이터가 어디에서 소유되고 관리 되는지를 나타내는 표현이다.
    여러 컨텍스트에서 사용되며, 주로 프로그래밍 언어나 소프트웨어 설계에서 사용됩니다.
    이것은 데이터에 대한 변경 및 접근 권한을 결정하고 관리하는 데 중요한 역할을 합니다.

    "Ownership"
    데이터의 소유권을 가진 곳은 해당 데이터를 생성하거나 할당한 곳을 의미합니다.
    이는 주로 변수, 객체, 또는 메모리와 같은 자원에 대한 소유권을 말합니다.
    데이터의 소유권이 있는 곳은 데이터에 대한 제어 권한을 가지며, 데이터를 수정하거나 삭제할 수 있습니다.
    또한 데이터를 공유하거나 전달할 때 소유권을 잃을 수 있습니다.
    이 개념은 프로그래밍에서 중요한데, 특히 메모리 관리와 관련하여 데이터의 소유권을 명확히 하는 것이 메모리 누수나 데이터 오염과 같은 문제를 방지하는데 도움이 됩니다.
    예를 들어 동적으로 할당된 메모리를 사용하는 경우 해당 메모리 블록의 소유권이 누구에게 있는지 추적하여 적절한 시점에 메모리를 해제해야합니다.

1.Client State

Ownership이 client에 있다.

  • client에서 소유하며 온전히 제어가능함.
  • 초기값 설정이나 조장에 제약사항 없음
  • 다른 사람들과 공유되지 않으며 client 내에서 ui/ux 흐름이나 사용자 인터랙션에 따라 변할 수 있음
  • 항상 client 내에서 최신 상태로 관리됨

2. Server State

Ownership이 Server에 있다.

  • Client에서 제어하거나 소유되지 않은 원격의 공간에서 관리되고 유지됨.
  • Fetching이나 Updating에 비동기 API가 필요함
  • 다른 사람들과 공유되는 것으로 사용자가 모르는 사이에 변경될 수 있음
  • 신경 쓰지 않는다면 잠재적으로 "out of date"가 될 가능성을 지님

React에서 QyeryClientProvider 필수!

import {QueryClient, QueryClientProvider} from 'react-query'

const queryClient = new QueryClient()

function App(){
return <QueryClientProvider client={queryclient}> ... </QueryClientProvider>

세 가지 core 컨셉 살펴보기
-Queries
-Mutations
-Query Invalidation


Queries

CRUD 중 Reading에만 사용할 것, Queries는 데이터 Fetching용

import {useQuery} from 'react-query'

function App() {
	const info = useQuery('Query Key', Query Funcrtion)
}
  • Query Key : Key, Velue 맵핑 구조
  • Query Key에 따라 query caching을 관리한다.
//string 형태
useQuery('todos', ...) //queryKey === ['todos']

//Array 형태
useQuery(['todos',5], ... ) //queryKey === ['todos',5]
useQuery(['todos',5,{preview:true}],...) // queryKey ===['todos',5,{ preview:  true}]

Query Funtion

Data Fetching 할 때 Promise 함수 만들죠?

  • Promise를 반환하는 함수.
    - 데이터를 resolve하거나 error를 throw
    useQuery('fetchOrder',() => fetchOrder(orderNo),option)

useQuery

  • data : 마지막으로 성공한 resolved된 데이터 (Response)
  • error : 에러가 발생 했을 때 반환되는 객체
  • isFetching : Request가 in-flight 중일 때 true
  • status, isLoding, isSuccess, isLoading 등등 : 모두 현재 query의 상태
  • refetching : 해당 query refetch하는 함수 제공
  • remove : 해당 query cache에서 지우는 함수 제공
  • etc.

useQuery Option

  • onSuccess, onError, onSettled : fetching 성공/실패/완료 시 실행할 side Effect 정의
  • enabled : 자동으로 query를 실행시킬지 말지 여부
  • retry : query 동작 실패 시, 자동으로 retry 할지 결정하는 옵션
  • select : 성공 시 가져온 data를 가공해서 전달
  • keepPreviousData : 새롭게 fetching 시 이전 데이터 유지 여부
  • refetchInterval : 주기적으로 refetch 할지 결정하는 옵션
  • etc.

Mutation

CRUD 중 Create / Update / Delete 에 모두 사용
Mutations는 데이터 생성 / 수정 / 삭제 용

const mutation = useMutation(newTodo => {
return axios.post('/todos', newTodo)
});

useQuery 보다 더 심플하게 Promise 반환 함수만 있어도 된다.
(단, Query Key 넣어주면 devtools 에서 볼 수 있다.)

useMutation

  • mutation : mutation을 실행하는 함수
  • mutateAsync : mutation 내부 상태 clean
  • reset : mutation 내부 상태 clean
  • 나머진 특별히 설명할 것 없이 useQuery랑 비슷 (오히려 반환하는 객체 안의 내용이 더 적다.)

useMutation Option

  • onMutate : 본격적인 Mutation 동작 전에 먼저 동작하는 함수, Optimistic update 적용할 때 유용
    - 성공할 것이라고 Optimistic하게 보고 UI에 반영, 실패 시 롤백
    (ex, 페이스북의 좋아요 기능)
  • 나머진 특별히 설명할 것 없이 useQuery랑 비슷 (오히려 Option이 더 적다.)

Query Invalidation

  • 간단히 queryClient를 통해 invalidate 메소드를 호출하면 끝
//Invalidate every query in the cache
queryClient.invalidateQueries()
//Invalidate every query with a key that starts with 'todos'
queryClient.invaldateQueries('todos')
  • 이러면 해당 key를 가진 query는 stale 취급되고, 현재 rendering 되고 있는 query들은 백그라운드에서 refetch 된다.
    - stale : 신선하지 않은, 즉 상한 데이터

참고
https://velog.io/@godud2604/React-Query%EC%99%80-%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC

0개의 댓글