반응형
설치
npm i react-query
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import 'index.css';
import { BrowserRouter } from 'react-router-dom';
import reportWebVitals from 'reportWebVitals';
import { Provider } from 'react-redux';
import { store } from 'store/rootReducer';
import GlobalStyle from 'styles/global-styles';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ThemeProvider } from 'styled-components';
import App from './App';
import 'react-app-polyfill/stable';
import 'core-js/stable';
import 'regenerator-runtime/runtime';
const theme: any = {
primaryColor: ['#a559f3', '#c282ef'],
subColor: ['#8178f9', '#a680fb'],
};
//------1
const queryClient = new QueryClient();
// GlobalStyle의 경우 컴포넌트 가장 상단에 위치해야 적용됨
ReactDOM.render(
//--------2
<QueryClientProvider client={queryClient}>
<Provider store={store}>
<ThemeProvider theme={theme}>
<GlobalStyle />
<BrowserRouter>
<App />
</BrowserRouter>
</ThemeProvider>
</Provider>
</QueryClientProvider>,
document.getElementById('root'),
);
리액트 프로젝트에서 사용하는 상태는 3가지 이다.
- local state : 리액트 컴포넌트 안에서 사용
- global state: 글로벌 store에 정의되어 어디서나 접근 가능함
- server state: 서버로 부터 받아오는 경우
리덕스에서 server state를 처리
액션에 따라 상태가 어떻게 변경되는지 리듀서(순수함수) 에서 정의를 한다. 동기적인 로직에서는 액션과 리듀서를 직관적으로 작성 가능하지만 비동기로직을 처리하기 위해서 미들웨어를 사용해야한다. (thunk , saga)
redux-thunk는 store에 던져진 액션을 가로채서 비동기 로직을 수행 후 액션을 발생시킴. 동기 로직에서 순수 객체였던 액션의 형태가 변경되어 어딘지 찜찜한 코드가 되고, 개발자는 액션을 스토어에 던진 후 상태가 언제 반영되는지 정확한 시점을 모르게 된다.
redux-saga를 사용하면 액션이 순수 객체의 모습을 되찾게 되지만 장황한 코드가 더욱더 많아짐...
실시간 업데이트도 구현해야하고, 동일한 컴포넌트 사용해도 여러번 api호출이 일어나며, 스토어가 global state , server state를 동시에 관리하면서 점점 복잡해진다.
React Query
React Query는 이 점을 해결할 수 있다.
- 선언적 프로그래밍 가능
- 동일한 api요청이 여러번 호출될 경우 한번만 실행
- 데이터가 dirty해진 경우 적절한 시점에 알아서 업데이트
- Global state와 server state 관심사 분리
React에서 서버 데이터를 최신으로 관리하기(React Query, SWR)
참고
useQuery
데이터 가져올때 사용
사용예시 >>>
export const getRanking = (options: any) => {
const res = useQuery(['getRanking', options], () =>
axios
.post(`${serverURI}${baseURI}/ranking`, options, {
timeout: 7000,
})
.then(response => {
if (response.data === '') {
throw Error;
}
return response.data;
}),
);
return res;
};
useQuery(['fetchWord', op], () => getWordTest(op));
const results = useQuery(['fetchWord', op], async () => {
const data = await getWordTest(op);
return data;
});
const results = useQuery(['fetchWord', op], () => getWordTest(op));
const queryClient = useQueryClient();
queryClient.setQueryData(`getWord`, options); //데이터 수정시 사용
queryClient.invalidateQueries(`getWord`); // api 재호출 시 사용 (지정된 key값을 넣는다)
useMutation
데이터 추가/삭제/수정 등 할때 사용
사용 예시>>>
const { mutate } = useMutation(getWordTest2, {
onMutate: variable => {
console.log('onMutate', variable);
// variable : {loginId: 'xxx', password; 'xxx'}
},
onError: (error, variable, context) => {
// error
},
onSuccess: (data, variables, context) => {
console.log('success', data, variables, context);
queryClient.invalidateQueries('getWord');
},
onSettled: () => {
console.log('end');
},
});
반응형
'개발(라이브러리,프레임워크) > react.js & react native' 카테고리의 다른 글
Recoil (0) | 2022.09.24 |
---|---|
React Transition Group 적용 중 이슈사항 (0) | 2022.07.02 |
react-transition-group (0) | 2022.06.08 |
ThemeProvider(styled-components) (0) | 2022.06.07 |
memoization (0) | 2022.05.22 |