밍부스26)미들웨어 공부하다 리액트쿼리까지 오게된 썰푼다.

minji jeon·2022년 8월 4일
0

TIL_

목록 보기
44/61
post-thumbnail

여기서 예제 공부하기

https://develop-neoguri.notion.site/Redux-React-Query-3faaf86a4dd6422f93b8f6988f9e6981
우선 리액트의 미들웨어를 공부하다
여기까지 오게되었다.

리액트 쿼리 당신은 누구인가요..?

-Serverstate library
-Managing asynchronous operations between your server and client
이렇게 두줄로 설명할수 있다.

서버상태라니 그럼 클라이언트 상태도 있겠구나
서버상태와 클라이언트 상태는 어떻게 다르지??

* 클라이언트 상태 : 뷰를 위한 데이터

  • 한 유저만을 위한 데이터 (세션간 지속될 필요없는 데이터) 예시) input 입력 값을 state로 관리(렌더링에 반영하기 위한 데이터)
    대표적으로 Redux, mobs, zustand가 있다.
  • 서버 상태 : 서버에서 가지고 오는 데이터
    • 여러 유저가 공유해야하는 데이터 (세션간 지속되어야 하는 데이터)
      예시) 게시물 리스트(DB에 저장되어 있는 데이터)
      우리가 어떤 데이터를 서버에 요청하고 나서 부터 요청을 받은 후까지 데이터를 받아오기 전까지 참조 못하게 하기, 게시글 목록 중 한 데이터 수정 api를 호출했다면 게시글 목록 자체를 리패칭하기 등 직접할 일이 참 많습니다. 리액트 쿼리는 이런 비동기 처리를 편히 할 수 있도록 굉장히 많은 기능을 제공해요. 😊 
      예를 들어, 관리자 화면에서 동시에 두 명의 관리자가 같은 페이지를 바라보고 있는 상황에서 한 관리자가 유저의 데이터를 변경하면, 다른 관리자도 그 유저의 변경된 데이터를 바라볼 수 있어야 합니다. 이러한 유저의 데이터는 클라이언트 쪽보다는 서버 쪽에 좀 더 적합하다고 볼 수 있습니다.

상태관리의 흐름이 다르다.
api요청을 보내는 것에 특화되어 있다.

  • fetching : 데이터 요청 중
  • fresh : 데이터를 갓 받아온 직후 / 컴포넌트의 상태가 변하더라도 데이터 재요청 하지 않음
  • stale : 데이터 만료 / 최신화가 필요한 데이터
  • inactive : 쿼리가 언마운트 된 상태 (더는 사용하지 않는 상태) !주의! 쿼리가 언마운트된다고 해서 비동기 요청이 취소되는 것은 아닙니다. 프라미스가 일단 만들어지고 언마운트된 거라면 데이터는 캐시에 살아 있을 수 있습니다. (공식문서에서 확인하기→)
  • delete : 완전히 삭제된 상태(캐시 데이터가 메모리에서 삭제!)
  • query : query key + query function
  • query key : 쿼리를 구분하기 위한 특정 값. 문자, 배열, 딕셔너리 등을 넣을 수 있음
  • query function : 서버에서 데이터를 요청하고 Promise를 리턴하는 함수(= 비동기 요청)
  • data : 쿼리 함수가 리턴한 Promise에서 resolve된 데이터
  • staleTime : 쿼리 데이터가 fresh 에서 stale로 전환되는데 걸리는 시간. 기본값은 0
  • cacheTime : unused 또는 inactive 캐시 데이터가 메모리에서 유지될 시간
    기본값은 5분이며 설정한 시간을 초과하면 메모리에서 제거
🔥

쿼리 : 리덕스의 스토어와 비슷
쿼리키값
쿼리펑션
—>쿼리 키값에 있는 무언가가 바뀌게 되면 자동으로 펑션을 요청. 자동실행 묻지도 따지지도 않고, 키값에 잇는 데이터를 바꿔벌임

🔥 Parallel queries(병렬 쿼리)는 후에 배워볼 suspense 모드에서 동작하지 않아요! 첫번째 쿼리가 프라미스를 만들면(서버 요청 등 비동기 요청을 보내면 프라미스가 만들어져요!) 다른 쿼리가 실행되기 전에 서스펜스가 동작을 일시 중지시켜버리기 때문인데요,

———
시작해보자!!
Npm I react-query
Nom I axis

index.js에서 초기세팅해주기

yarn remove react-query && yarn add react-query@3
이또한 버전이슈가 있었다.
지금은4버전
강의는 3버전…. ㅠㅠㅠ
yarn remove react-query && yarn add react-query@3
해결..

👉 QueryClient는 QueryClientProvider와 한쌍입니다. 상태를 주입할 Provider로 감싸주고, 쿼리 클라이언트를 주입해요!
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
import './index.css';
import { QueryClient, QueryClientProvider } from 'react-query';
//import { useQuery } from '@tanstack/react-query''
//import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { ReactQueryDevtools } from "react-query/devtools";

const queryClient = new QueryClient();
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
   /// 
   <Provider store={store}>
  <QueryClientProvider client={queryClient}>
    <ReactQueryDevtools initialIsOpen={true} />
        <App />
        </QueryClientProvider>
    //</Provider>
 
);

app.js
useQuery는 어떤 데이터를 가져와서 캐싱하기 위해 씁니다! 쿼리 키, 쿼리 함수, 옵션으로 구성되어 있어요. - 쿼리 키 : 문자열 / 배열 등을 넘길 수 있습니다. 이 키는 캐싱 처리하는데에 사용해요. 우리가 불러다 쓰기 위해서도 중요합니다. - 쿼리 함수 : Promise를 리턴하는 어떤 함수를 넘깁니다. api와 통신하는 함수가 주로 들어가요. - 옵션 : useQuery()를 위한 옵션들을 넣어주면 됩니다!

const my_first_query = useQuery(쿼리 키, 쿼리 함수, 옵션);

  • my_first_query에는 아래같은 데이터가 담겨요.
    • data : 서버 요청에 대한 데이터
    • isLoading : 캐시가 없는 상태에서의 데이터 요청 중인 상태 (true / false)
    • isFetching : 캐시의 유무 상관없이 데이터 요청 중인 상태 (true / false)
    • isError : 서버 요청 실패에 대한 상태 (true / false)
    • error : 서버 요청 실패 (object)
    • refetch : 데이터를 새로 패칭하는 함수
  • 넘길 수 있는 옵션 중 알아두면 좋을 내용입니다.
    • cacheTime : 언마운트된 후 어느 시점까지 메모리에 데이터를 저장하여 캐싱할 것인지를 결정 기본 값 : 30000(5분)
    • staleTime : 쿼리가 fresh 상태에서 stale 상태로 전환되는 시간 기본 값 : 0
    • refetchOnMount : 컴포넌트 마운트시 새로운 데이터 패칭 기본 값 : true (false일 경우엔 마운트해도 새로운 데이터를 가지고 오지 않아요.)
    • refetchOnWindowFocus : 브라우저 클릭 시 새로운 데이터 패칭 기본 값 : true (false일 경우엔 다른 탭으로 갔다가 돌아와도 데이터를 새로 가져오지 않아요.)
    • refetchInterval : 지정한 시간 간격만큼 데이터 패칭 / 브라우저 바깥에 있을 경우(다른 탭에 있는 등) 실행되지 않아요! 기본 값 : 0
    • refetchIntervalInBackground : 브라우저에 포커스가 없어도 refetchInterval에서 지정한 시간 간격만큼 데이터 패칭 기본 값 : false
    • enabled : 컴포넌트가 마운트 되어도 데이터 패칭 ❌ 기본 값 : true useQuery의 리턴 값 중 refetch가 있었죠! enabled가 true일 때는 refetch를 통해 데이터를 패칭해야 합니다.
    • onSuccess : 데이터 패칭 성공 시 콜백 함수
    • onError : 데이터 패칭 실패 시 콜백
    • initialData : 초기 데이터 쿼리 생성 전이나 아직 캐싱되지 않았을 경우, 이 데이터를 초기 데이터로 써요!
    • select : 데이터 패칭 성공 시 가져온 데이터를 변환해주고 싶을 때, 원하는 데이터 형식으로 변환하기 위한 콜백 (여기서 return으로 변환한 데이터를 반환해주면 useQuery의 결과값인 data가 변해요.)

get방식 연습

const 실행함수 = () => {
return axios.get('http://localhost:4000/sleep_times')
}

function App() {
const 어떤쿼리 = useQuery("쿼리키",실행함수, {
onSuccess: (data) => {
console.log(data)
},
onError: () => {
console.log("왜안되지?")
}
})
//옵션에 stale time을 추가해주면 해당 주기마다 서버를 refresh해준다.
서버에서 데이터를 관리하기 편하다
최신데이터를 유지하기 편하다

if (어떤쿼리.isLoading) { //is loading이 내장되어 있다.
return null;
}

console.log(어떤쿼리.data.data)
이렇게 키를 입력하면 된다.

post방식 연습
1.
const api요청함수post = (data) => {
return axios.post("http://localhost:4000/sleep_times", data);
};

  1. Usemutation
    const { mutate } = useMutation(api요청함수post);

  2. 이벤트
    onClick={() => {
    const data = {
    day: 요일.current.value,
    sleep_time: 시간.current.value,
    };
    mutate(data);
    }}
    //바로 반응이 안된다. —>캐싱된 데이터를 처리해주지 않기 위해

후처리 해주기
const queryClient = useQueryClient();

const { mutate } = useMutation(api요청함수post, {
onSuccess: () => {
// 캐싱처리 : 추가한 데이터를 mutate가 가지고 잇어서 화면에 반영이 안된다. 그래서 너 이거 버려!
//수면 데이터 목록을 다시 불러오면 ok
queryClient.invalidateQueries("쿼리키"); //이렇게 하면 바로넘어온다.
},
});
읽어보면 좋은 자료
https://tech.kakao.com/2022/06/13/react-query/
어떤 상황에서 React Query를 사용하면 좋을까?
클라이언트 사이드의 데이터보다는 서버 사이드의 데이터 관리가 더 많을 때 유용하게 쓰일 있다고 생각합니다.
예를 들면, Admin 페이지와 같은 관리형 페이지에서는 클라이언트의 전역 상태 데이터는 많이 필요하지 않을 수 있습니다. 이러한 페이지에서 Ducks 구조보다는 React Query를 적용하면 구조를 더 단순화 시킬 수 있습니다.
또한, refetching 옵션들을 통해 서버의 데이터를 동기화할 수 있고, useMutation을 사용할 때도, defaultOptions에 onError를 추가하여, POST, PUT, DELETE 등의 API 실패 시, 안내 문구를 띄우는 기능도 유용하게
리액트 쿼리
https://develop-obm.tistory.com/32

react-query는 서버의 값을 클라이언트에 가져오거나, 캐싱, 값 업데이트, 에러핸들링 등 비동기 과정을 더욱 편하게 하는데 사용됩니다.
사용하는 이유
저의 경우 서버로 부터 값을 가져오거나 업데이트 하는 로직을 store 내부에 개발하는 경우가 많습니다. 그렇다보니 store는 클라이언트 state를 유지해야하는데 어느 순간부터 store에 클라이언트 데이터와 서버 데이터가 공존 하게 됩니다. 그리고 그 데이터가 서로 상호작용하면서 서버 데이터도 클라이언트 데이터도 아닌 끔찍한 혼종(?)이 탄생하게 됩니다. (예를 들면 서버에는 이미 패치된 데이터가 클라이언트에서는 패치되기 전 데이터가 유저에게 사용되고 있는 것이라고 볼 수 있습니다.)
그래서 react-query를 사용함으로 서버, 클라이언트 데이터를 분리합니다. 이 개념에 대해 동의 하지 않아도 아래의 장점을 보신다면 사용하고 싶은 생각이 드실 것입니다.

react-query 장점
여러가지 장점이 있지만 주로 아래와 같이 프론트 개발자가 구현하기 귀찮은 일들을 수행합니다.

  • 캐싱
  • get을 한 데이터에 대해 update를 하면 자동으로 get을 다시 수행한다. (예를 들면 게시판의 글을 가져왔을 때 게시판의 글을 생성하면 게시판 글을 get하는 api를 자동으로 실행 )
  • 데이터가 오래 되었다고 판단되면 다시 get (invalidateQueries)
  • 동일 데이터 여러번 요청하면 한번만 요청한다. (옵션에 따라 중복 호출 허용 시간 조절 가능)
  • 무한 스크롤 (Infinite Queries (opens new window)
)
  • 비동기 과정을 선언적으로 관리할 수 있다.
  • react hook과 사용하는 구조가 비슷하다.

profile
은행을 뛰쳐나와 Deep Dive in javascript

1개의 댓글

comment-user-thumbnail
2022년 8월 6일

cffg

답글 달기