그냥 블로그

[WALFI] Recoil + React Query 도입 본문

프로젝트/WALFI

[WALFI] Recoil + React Query 도입

코딩하는 공대생 2024. 6. 14. 23:18
반응형

1. Recoil 

Recoil을 사용하면 atoms에서 selectors를 거쳐 React 컴포넌트로 내려가는 data-flow graph를 만들 수 있다. 
Atoms는 컴포넌트가 subscribe할 수 있는 state의 단위이며, selectors는 atoms의 상태값을 동기 또는 비동기 방식을 통해 변환한다. 

 

Atom

 

state에 대한 정보를 나타내는 객체,

key : atom을 식별하는데 사용되는 고유한 문자열, 어플리케이션 전체에서 다른 atom과 selecor에 대해 고유함.

defaultatom의 초깃값 또는 Promisee 또는 동일한 타입의 값을 나타내는 다른 atom이나 selector. 

function atom<T>({
  key: string,
  default: T | Promise<T> | RecoilValue<T>,

  effects_UNSTABLE?: $ReadOnlyArray<AtomEffect<T>>,

  dangerouslyAllowMutability?: boolean,
}): RecoilState<T>

const todoListState = atom({
  key: 'TodoList',
  default: [],
});

 

Atom과 상호작용하기 위해 자주 사용되는 Hooks
  • useRecoilState() : atom을 읽고 쓰기
  • useRecoilValue() : 읽기 전용
  • useSetRecoilState() : 쓰기 전용
  • useResetRecoilState() : atom을 초깃값으로 초기화
Selector

 

파생된 state, atoms나 다른 selectors를 입력으로 받아들이는 순수 함수

 

key위와 동일

get 함수 :

  • 제공 시 Selector는 읽기만 가능한 RecoilValueReadOnly를 반환
  • 값을 직접 반환하거나 비동기 Promise 또는 같은 유형을 나타내는 다른 atom, selector을 반환 가능
  • get : 다른 atom이나 selector로부터 값을 찾는데 사용되는 함수. 이 함수에 전달된 모든 atom과 selector는 암시적으로 selector에 대한 의존성 목록에 추가된다.  

set? 함수 :

  • 제공 시 쓰기 가능한 RecoilState 객체 반환
function selector<T>({
  key: string,

  get: ({
    get: GetRecoilValue
  }) => T | Promise<T> | RecoilValue<T>,

  set?: (
    {
      get: GetRecoilValue,
      set: SetRecoilState,
      reset: ResetRecoilState,
    },
    newValue: T | DefaultValue,
  ) => void,

  dangerouslyAllowMutability?: boolean,
})

 

const toggleState = atom({key: 'Toggle', default: false});

const mySelector = selector({
  key: 'MySelector',
  get: ({get}) => {
    const toggle = get(toggleState);
    if (toggle) {
      return get(selectorA);
    } else {
      return get(selectorB);
    }
  },
});

const proxySelector = selector({
  key: 'ProxySelector',
  get: ({get}) => ({...get(myAtom), extraField: 'hi'}),
  set: ({set}, newValue) => set(myAtom, newValue),
});

// 이 selector는 데이터를 변환하므로 입력 값이 DefaultValue인지 확인해야 함.
const transformSelector = selector({
  key: 'TransformSelector',
  get: ({get}) => get(myAtom) * 100,
  set: ({set}, newValue) =>
    set(myAtom, newValue instanceof DefaultValue ? newValue : newValue / 100),
});

// 비동기 Selector
const myQuery = selector({
  key: 'MyQuery',
  get: async ({get}) => {
    return await myAsyncQuery(get(queryParamState));
  },
});

 

Lodable

 

atom 혹은 selector의 최신 상태를 대표. state contents 두 가지 데이터를 가짐

 

state : atom 혹은 selector의 최신 상태. 가능한 값은 'hasValue', 'hasError' 혹은 'loading'

contents : Loadable에 의해 대표되는 값. 만약 상태가 hasValue라면, 이는 실제 값이다. 만약 hasError라면 이는 던져진 Error 객체이다. 만약 상태가 'loading;이라면 toPromise()를 사용해 값의 Promise를 얻을 수 있다. 

 

function UserInfo({userID}) {
  const userNameLoadable = useRecoilValueLoadable(userNameQuery(userID));
  switch (userNameLoadable.state) {
    case 'hasValue':
      return <div>{userNameLoadable.contents}</div>;
    case 'loading':
      return <div>Loading...</div>;
    case 'hasError':
      throw userNameLoadable.contents;
  }
}

 


2. React-Query

1) 간편한 데이터 관리

- 데이터 가져오기, 캐싱, 동기화 및 업데이트 처리 간편화 

2) 실시간 업데이트 및 동기화

- 실시간 데이터 업데이트와 자동 동기화 지원 => 서버와 클라이언트 데이터 일관성 유지

3) 데이터 캐싱

- 데이터 캐싱, 불필요 API 요청을 줄이고 애플리케이션 성능 향상 

4) 서버 상태 관리

- 서버 상태 관리 (예를 들면 로딩중, 에러, 성공 등의 상태)를 간편 처리

5) 간편한 설정 

 

설치

 

먼저, react-query를 설치해주고, eslint-plugin-query까지 설치해줌.

yarn add @tanstack/react-query
yarn add @tanstack/react-query-devtools
yarn add @tanstack/react-query-next-experimental
$ yarn add -D @tanstack/eslint-plugin-query

 

eslint에서 react-query에 대해 플러그인을 추가해 줘야 한다. 그렇지 않으면 오류가 뜨는 듯... 

에러 안없어지면 IDE 껐다 키세용

'@tanstack/react-query' should be listed in the project's dependencies. Run 'npm i -S @tanstack/react-query' to add it
//eslintrc.json
"extends":["plugin:@tanstack/eslint-plugin-query/recommended"]

 

GET

 

POST

 

 

 

[Recoil 공식 문서]

 

Atoms | Recoil

Atoms contain the source of truth for our application state. In our todo-list, the source of truth will be an array of objects, with each object representing a todo item.

recoiljs.org

[Recoil 폴더 구조 참조]

 

Recoil 도입기(feat. 폴더구조)

React 18로 버전업 하면서 프로젝트에 Recoil을 도입했는데, 그 과정에서 고민했던 내용을 기록차 남겨본다. TL;DR; 개념 정리나 장단점 비교에 대해서는 이미 알고 계신분들도 있을 것 같아서 폴더구

soobing.github.io

 

https://velog.io/@gygy/Next.js-14%EC%97%90%EC%84%9C-React-query-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

Next.js 14에서 React-query 사용하기

Next.js에서 React-query를 사용하려면 React 프로젝트와는 조금 다르게 환경을 세팅해야 합니다. 13버전 이후부터는 RSC가 도입되어 가장 상위 모듈인 layout에서 QueryProvider로 QueryClient를 props로 내려줄

velog.io

[ESLint plguin : React-query]

 

ESLint Plugin Query | TanStack Query Docs

Does this replace [Redux, MobX, etc]? react

tanstack.com

 

[추천 자료]

 

Next.js app router에서 React Query 사용하면서 고민했던 것들

지난 글에서 react-query의 hydrate, dehydrate을 통해 서버에서 prefetching 한 데이터 사용하는 방법에 대해서 살펴보았습니다. 서버에서 prefetching 한 데이터 사용하기 오늘은 조금 실용적으로 Next.js 13, 14

soobing.github.io

 

 

[React-query 공식문서]

 

https://tanstack.com/query/latest/docs/framework/react/guides/advanced-ssr#prefetching-and-dehydrating-data

 

Advanced Server Rendering | TanStack Query React Docs

Welcome to the Advanced Server Rendering guide, where you will learn all about using React Query with streaming, Server Components and the Next.js app router. Before we start, let's note that while the initialData approach outlined in the SSR guide also wo

tanstack.com

 

'프로젝트 > WALFI' 카테고리의 다른 글

[Back-end] 스프링 부트/JSP 폴더 구조와 각 기능  (0) 2024.06.13
메타 데이터  (0) 2024.05.29
[Next.js]  (0) 2024.05.24
[Next.js] 정적 및 동적 렌더링  (0) 2024.05.22
[Next.js] app router + React Query  (0) 2024.05.20