본문 바로가기
개발(라이브러리,프레임워크)/react.js & react native

react-query

by zieunee 2022. 6. 12.
반응형

설치

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