
#React- Query
React-Query는 데이터 가져오기, 캐싱, 동기화 등 서버상태를 관리할 수 있게 해주며,
다른 컴포넌트 끼리도 key를 이용하여 선언한다면 이는 결은 다르지만 redux같이 상태공유 같이
캐싱된 데이터를 공유할 수 있도록 하여 불필요한 요청을 줄이고 어플리케이션의 성능 향상시키는
강력한 라이브러리이다.
#React-Query 사용하는 이유 '예시'
예로 SPA 형식의 웹페이지에서 게시판을 만든다고 가정한다면 CRUD 기능 이후 데이터 무결성을 위해서
CRUD 기능 이후 서버에 해당 로직에 필요한 데이터를 재 요청하여 상태업데이트를 해야한다.
AS-IS 방식
const [ board , setBoard ] = useState({
board : '게시판 이름',
boardContents : [...],
board_cnt : null
})
보통 위 같은 State를 가진 board라면 'board_cnt' 값을 가지고 페이징을 하고 boardContents의 배열 객채를 map()을 이용해서 게시판 데이터를 구성할 것 이다.
그럼 Create 나 delete 할 경우에 데이터는 데이터베이스와 클라이언트의 데이터의 무결성을 지키기 위해 신규 데이터를 리턴 받아서 사용자에게 직관적으로 보여줄 필요가 있다.
그렇다면 상태 업데이트를 해줘야 하는 로직이 필요하다
const createBoard = async(data) => { .... } // Create Fetch 로직
const onSubmitHandler = async(e) =>{
//... 폼데이터 처리 전달
try{
const refrashData = await createBoard('form 데이터 전달');
//상태 업데이트
setBoard(prev => ({...prev ,
boardContents : refrashData.contents ,
board_cnt : refrashData.cnt
}))
}
catch(error){
//에러처리 !
}
}
setBoard를 처리해서 상태를 업데이트 시켜 재 랜더링을 유도 시켜야 클라이언트에서도 서버와 동일한 데이터를 보여줄 수 있는데 이 로직을 'react-query'를 이용하면 상태 훅을 선언하고 업데이트 해줘야 하는 로직을 만들 필요가 없어진다.
react-query에서 서버 데이터 상태를 자체적으로 관리 할 수있기 때문이다.
#React-Query 설치 및 세팅
역시나 패키지로 설치부터 해야한다.
"리액트는 라이브러리를 반 강제적으로 사용해야 편한 DX가 가능하다란 점 기억하기"
npm install react-query
react-Query는 트리형태 데이터를 공급하기위해 provider를 선언해야한다.
react-query의 메서드인 "QueryClientProvider" , "QueryClient"를 최 상위 컴포넌트에 선언한다.
일반적으로 최상단에서 한번 선언한다.
import { QueryClient , QueryClientProvider } from 'react-query';
const queryClient = new QueryClient();
root.render(
<QueryClientProvider client={queryClient} > // provider 와 queryClient 선언
<React.StrictMode>
<App />
</React.StrictMode>
</QueryClientProvider>
);
"QueryClient"는 react-query의 핵심기능을 가지고있는 인스턴스로 서버 상호작용에 의한 서버 상태 등을 관리, 캐싱, 데이터 동기화 등을 수행하여 이를 자식 컴포넌트 들에게 전달하기위해 "QueryClientProvider"를 사용하여 react Query의 기능을 하위 컴포넌트들이 사용 할 수 있도록 해주는 공급한다.
#useQuery , useMuation
const { data , isLoading , error }= useQuery('id' , fetchData);
"useQuery"는 첫번째 매개변수를 식별자로 key , 'id' 를 사용하며, 두번째로는 비동기함수를 주로 fetch나 서버로 통신하는 함수를 많이 사용한다. useQuery는 비동기 함수로 패칭된 데이터를 캐싱하고 data, isLoading ,error 등의 객체를 반환한다
data : 비동기 함수가 서버요청에서 리턴 받은 데이터를 담은 프로퍼티
isLoading : 현재 데이터요청, 종료 상태를 boolean값으로 나타낸다.
error : 에러
"useMutation"은 데이터변경 CRUD을 작업처리를 위해 사용된다.
A컴포넌트와 B컴포넌트로 나뉜 컴포넌트라도 상위 컴포넌트에 QueryClientprovider로 트리구조로 구성해두었기 때문에 상태를 useQueryClient 훅으로 손쉽게 데이터를 동기화하여 useState의 set등을 하지 않아도 공유가 가능하다.
//A 컴포넌트
const { data , isLoading , error } = useQuery('id', fetchData );
//B 컴포넌트
const queryClient = useQueryClient();
const { mutate , isLoading ,isSuccess , data } = useMutation(data => requestFetch(data), {
onSucess : (data)=>{
queryClient.invalidateQueries('id');
alert('성공!');
},
onError : (error)=>{
//에러처리
alert(error.message);
}
})
A,B 컴포넌트는 서로 다른 컴포넌트여도 invalidateQueries를 'id' 키를 가진 useQuery에 데이터를 동기화 시킨다.
뮤테이션이 성공하면 윗 로직의 패치가 성공 된 이후 세번째 매개변수 옵션(onSuccess, onError)을 이용하여 완료,에러 추가 로직을 구성 할 수 있으며 또 isSuccess 프로퍼티를 이용하여도 추가 처리를 해도 된다.
useMutation의 반환객체인 "mutate"는 비동기함수를 실행하도록 하는 프로퍼티이며, "data"는 완료 후의 데이터 즉, useQuery에 캐싱한 후 동기화 된 데이터를 참조하고 있는 프로퍼티이다.
AS-IS방식으로는 매번 상태에 set하고 다시 랜더링 시키고 불필요한 패치를 할 경우가 있지만 이 라이브러리를 이용하여 매우 간편하게 서버데이터 동기화가 가능하다
24/3/1추가
"Mutate , MutateAynsc"
Mutate, MutateAynsc 둘다 useMutation의 실행 조작을 담당하는 프로퍼티로 둘 다 비동기적으로 실행된다.
다만 MutateAynsc는 프로미스를 반환함으로 외부에서 추가 로직이 수행가능하며 mutate는 프로미스를 반환하지 않기에 특정 fetch를 실행할때 사용한다.
둘 다 콜백함수로 onSuccess , onError로 후속 조치가 가능하다.
mutateAynsc는 다른 비동기 함수와 더불어 추가 로직을 실행하기에 적합하며, mutate는 fire-and-forget방식으로 처리 할때 유용하다.
#useQuery를 이용한 페이징 처리
예로 게시판에 10개씩 나누어 페이징 처리된 게시판이 있다고 가정하고 페이징 할때마다 쿼리스트링을 이용해서 10개씩 데이터를 반환 받아야한다.
이때 useQuery의 의존성( Dependeny ) 을 이용하여 간단하게 처리 가능하다.
우선 page를 가져오고..
const url = new URL(window.location);
const page = url.searchParams.get('page') || 1;
page를 ['id',page]로 반영한다. 이때 id는 key와 동일하고, page는 의존성으로 구별된다.
const url = new URL(window.location);
const page = url.searchParams.get('page') || 1;
const { data } = useQuery(['id', page], (data)=>fetchData(data))
page가 변경되면 fetchData는 재 실행이 되며 별도의 로직이 필요없이도 10개씩 나누어진 데이터를 반환 받을 수 있다.
'React' 카테고리의 다른 글
| [React-Hook-Form] watch ,reset ,setValue (0) | 2024.03.01 |
|---|---|
| [React] Css in js / Styled.component (0) | 2024.02.03 |
| [React-datePicker] 시작날짜, 종료날짜 컴포넌트 만들기 (1) (1) | 2024.01.27 |
| React - Router [ action , loader ] (2) | 2024.01.09 |
| React - useMemo (1) | 2023.12.09 |