[React] Recoil이 뭔데 대체! / React를 위한 상태 관리 라이브러리 Recoil 개념 쉽게 알아보기

2022. 6. 9. 00:10React

    목차

 

"상태 관리가 필요한 이유"


컴포넌트에서 다른 컴포넌트로 값을 넘기는 방법은 2가지가 있습니다!

1) 부모컴포넌트 => 자식 컴포넌트로 props 넘기기
2) 상태관리 라이브러리 (Redux, Recoil 사용하기)

출처: reocil 공식 유튜브

만약 1) 부모=> 자식 컴포넌트로 props 넘기기를 이용하여

꼭대기 Provider1 ==>  마지막 6 로 값을 전달하면 어떤 문제가 발생할까요?

 

A. Traveling Props가 발생!

 

Traveling Props란?

여행하는 Props란 뜻으로

props가  전달=>전달=> 전달=>하게 되어

이리 저리 컴포넌트 세계여행을 떠나게됩니다.

그렇게 되면 코드가 굉장히 복잡해지고 번거로워지고 헷갈리게 되겠죠?

 

 

 

그러나, Recoil과 같은 상태관리 라이브러리를 사용하게 되면,

직통열차처럼 한 번에 값을 전달할 수 있게 됩니다!

 

 

 

 

 

그렇다면 Recoil의 기본개념을 알아봅시다~

 

Recoil의 atom, selector를 숙지한다면recoil의 대부분을 마스터 했다고 해도  과언이 아니랍니다!

 

 

Atom:  Recoil에서 제공하는 데이터 상태의 단위이며, 업데이트가 가능합니다.
redux에서 쓰이는 store 와 유사한 개념입니다.

 

Selector:
-atom의 state를 가져와서, 새로운 state를 만들어 반환합니다.
- 기존 state를 이용할 뿐, 원본을 바꾸지 않습니다.
- atom처럼 컴포넌트가 이를 구독할 수 있습니다. 

 

 

 

(1) useRecoilState() : 상태값을 가져오고 수정할 수 있다.

(2) useRecoilValue() : 상태값을 가져오기만 한다.(read only)

(3) useSetRecoilState() : 상태값을 수정할 수만 있다. (write only)

(4) useResetRecoilState() : 상태값을 초기값으로 리셋한다.

 

 

 

쉽게 예를 들어볼게요!

배달 사이트를 만든다고 가정합시다.

 

회원정보 atom이라는 방울  안에  회원정보를 넣고,

배달정보 atom에 배달정보를 넣었습니다.

 

Atom.js에서 선언을 했습니다

 

 

 

 

 

다음과 같이 세 개의 컴포넌트에서 atom을 구독하고 있습니다

그 컴포넌트들은 똑같은 상태를 공유할거예요.

(즉, 상태가 바뀌면 컴포넌트들이 바뀐 값으로 재랜더링됩니다.)

 

 

 

 

Login.js에서는 useReocilValue()를 사용하여, 회원정보를 가져올 수 있습니다

 

Update.js에서는 useSetRecoil() 함수를 사용하여, 배달정보를 마라탕 주문을 추가 업데이트했습니다!

이런 식으로의 로직이 이루어지는데요 코드를 통해 추가로 살펴보겠습니다

 

 

recoil 환경설정

 

1. npm으로 Recoil 패키지를 설치합시다
npm install recoil

 

2. index.tsx 안에서<RecoilRoot>로 <App>을 감싸줘야합니다
//index.tsx

import React from 'react';
// import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import { RecoilRoot } from 'recoil';
import App from './App';

// React 18        
const container = document.getElementById('root') as HTMLElement;
const root = createRoot(container);

root.render(
    <React.StrictMode>
      <RecoilRoot>
          <App />
      </RecoilRoot>
    </React.StrictMode>,

 

3. atom은 key와 default값을 선언을 해야합니다
import { atom } from "recoil";

export const menuAtom= atom({
 key: "menu",
 default:""
});

* key: atom을 식별하는데 필요한 유니크한 문자열

* default: 초기값을 설정해줍니다.  초기값은 string의 null값인 ""로 설정했습니다!

 

 

//App.tsx
//메뉴를 주문 컴포넌트 

import React from "react";
import { useRecoilState } from "recoil";
import { menuAtom} from "./componets/atom";
import MyPage from "./componets/MyPage";

function App() {
  const setMenu = useSetRecoilState(menuAtom);
  //useSetRecoilState(menuAtom); menuAtom의 값을 수정할 수 있음

//onChange 함수
  const onOrderChange = (e: React.FormEvent<HTMLInputElement>) => {
    setMenu(e.currentTarget.value); 
    //Menu setter
    
  }; 

  return (
    <>
      <input
        onChange={onOrderChange}
        type="string"
        placeholder="메뉴를 주문해보세요"
      ></input>
   	  <MyPage></MyPage>
    </>
  );
}

export default App;

 

  const setMenu = useSetRecoilState(menuAtom);

 

useSetReocilState는 writeonly 함수를 반환합니다. 

이로써 setMenu를 통해 사용자가 주문한 메뉴로  상태를 null =>  주문한 메뉴로 바꿀 수 있습니다

실행화면

//MyPage.tsx

import { useRecoilValue } from "recoil";
import { menuAtom } from "./atom";

function MyPage() {
const myMenu = useRecoilValue(menuAtom);
//atom의 상태값을 가져옴!
    
return(
        <>
        <h1>하연이가 주문한 메뉴는 {myMenu}</h1>
        </>
    )


}
export default MyPage;

 

 

const myMenu = useRecoilValue(menuAtom);

useRecoilValue(menuAtom)를 통해

App에서 주문한 값을 변수로 가져올 수 있습니다!

 

 

 

 

 

실행화면

사용자가 App.tsx에서 작성한 menu를

MyPage 컴포넌트에서 읽고있음을 알 수 있습니다!

props로 값을 넘기지 않았음에도 atom에서 값을 가져오고, 수정하는 것을 볼 수 있습니다! 

너무 편리하지요 ?

 

그다음 게시물에서는 selector에 대해 공부하고! 배워보도록 합시다!!!!!!!