글로벌 스테이트

wooo·2023년 5월 1일
0

글로벌 스테이트

사이트를 만들다보면 하나의 state가 여러 페이지에서 필요한 경우가 있다. 예를들면 isLogined 같은 state는 게시글 목록이나 결제 컴포넌트 같이 여러가지 컴포넌트에서 사용된다. 이러한 state는 매번 props로 내려주는 것보다 글로벌 스테이트를 사용하면 편리하다.

글로벌 스테이트(global state)


글로벌 스테이트는 여러 컴포넌트에서 사용되는 state이다. 위의 그림을 보면 srote에 name이라는 state를 저장해두고 필요한 컴포넌트에서 import하여 사용하기 때문에 props drilling을 하지 않아도 되고 굉장히 편리하다.
이런 전역상태관리(global state) 툴로는 context-Api, Redux, Recoil 등이 있다.
다만 Redux는 너무 어렵고 비효율적이기 때문에 context-api와 recoil을 주로 사용한다.

FetchPolicy

recoil과 context-api를 보기전에 apollo-client의 고급 기능을 먼저 알고 가면 도움이 된다.
여러 컴포넌트가 있고, 여러 컴포넌트들이 공유할 수 있는 global state가 있다고 가정한다. 이때 apollo-client로 global state를 만들게되면 apollo-cache라는 곳에 저장되게 된다.

만일 2번 컴포넌트에서 useQuery를 해오게 되면 useQuery를 해서 받아온 데이터가 Apollo-cache에 저장된 후 컴포넌트로 들어오게 된다.

이후 3번 컴포넌트에서 같은 데이터를 요청하게 되면 apollo-cache에 먼저 가서 데이터가 있는지 확인한다. 이때 데이터가 없으면 백엔드에 요청을, 데이터가 있으면 백엔드에 요청을하지 않고 컴포넌트로 바로 보내주게 된다.

이를 Apollo-client의 fetchPolicy(fetch 정책)라고 한다.
fetchPolicy에는 여러가지 기능들이 있으며 변경도 가능하다.

"cache-first" default -> 캐시에 데이터가 있는지 먼저 확인
"network-only" -> 캐시에 있든 없든 무조건 백엔드에 요청

Recoil

프론트에서 자체적으로 생성되는 데이터는 어디에 넣어두지?라고 했을 때 몇가지 방안들이 있지만 여기서는 recoil이라는 라이브러리를 사용해볼 예정이다.

프론트에서 관리하는 데이터라고 해봤자 많은 부분을 차지하지 않을텐데 리덕스를 사용하기에는 너무 헤배하기 때문에 recoil을 사용하며, recoil을 사용하기 위해서는 먼저 설치가 필요하다.

Recoil 설치

  1. npm 사용자 : 터미널에 npm install recoil 을 입력한다.
  2. yarn 사용자 : 터미널에 yarn add recoil 을 입력한다.

Recoil 세팅

세팅은 app.tsx 파일에 하면 된다.

//app.tsx 파일 
import {
  RecoilRoot,
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
} from 'recoil';

function App() {
  return (
    <RecoilRoot>
		//RecoilRoot로 모든 컴포넌트를 묶어주세요
      <Component />
    </RecoilRoot>
  );
}

Recoil 사용

Recoil에서는 Atom으로 state의 일부를 보여준다.
그리고 컴포넌트들은 자신이 필요한 Atom을 참조하고 있다. 따라서 자신이 참조하고 있는 Atom에 변화가 있으면 해당 Atom을 참조하는 모든 컴포넌트에서 리렌더링이 일어난다.

// Atom
const textState = atom({
  key: 'textState', // state의 이름
  default: '', //초기값
});

🚀 Atom 파일을 꼭 분리해줘야 하는 것은 아니지만 파일을 분리할 경우 반드시 export를 해주어야한다.

Atom을 실제로 사용하기 위해서는 useRecoilState를 사용해야한다. 사용법은 useState와 비슷하다.

// TextInput 컴포넌트 
function TextInput() {
  const [text, setText] = useRecoilState(textState);

  const onChange = (event) => {
    setText(event.target.value);
  };

  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo: {text}
    </div>
  );
}

위와 같이 사용하면 textState를 참조하는 모든 컴포넌트에서 리렌더가 일어난다.
Recoil은 결국 context-api의 단점을 보완한 상태관리 라이브러리이기 때문에 context-api를 기반으로 하고 있다.

0개의 댓글