티스토리 뷰

지난 5월, Facebook에서 새로운 React 상태 관리 라이브러리를 발표하였습니다.

Facebook에서 공식으로 지정한 상태 관리 라이브러리는 아니지만, 처음 개발한 상태관리 라이브러리라는 점에서 큰 주목을 받고 있습니다.

아직은 실무에 적용하기에는 이른 베타 버전(v0.0.13) 입니다.

점유율이 점차 증가하고 하고 있고 해외에서는 Redux 만큼 관심이 뜨겁다고 합니다.

 

Recoil 세팅

  
  $ create-react-app app
  $ cd app
  $ yarn add recoil
  

 

Recoil 튜토리얼에서는 ESLint 설정을 권장하고 있습니다.

    
  {
    "plugins": [
      "react-hooks"
    ],
    "rules": {
      "react-hooks/rules-of-hooks": "error",
      "react-hooks/exhaustive-deps": [
        "warn", {
          "additionalHooks": "useRecoilCallback"
        }
      ]
    }
  }

useRecoilCallback 함수의 의존성이 잘못 지정된 경우 ESLint에서 경고를 발생시켜 수정하도록 합니다.

 

실제 코드를 작성해보도록 하겠습니다.

App.js

  
  import React from 'react';
  import {
    RecoilRoot,
    atom,
    selector,
    useRecoilState,
    useRecoilValue,
  } from 'recoil';

  function App() {
    return (
      <RecoilRoot>
          {/* 여기에 컴포넌트를 작성합니다 */}
      </RecoilRoot>
    );
  }

  export default App;

<RecoilRoot>는 Redux에서 Provider와 동일한 역할을 수행합니다.

Recoil에 의해 상태 관리받기를 원하는 컴포넌트들을 감싸주면 되겠습니다.

CRA의 React면 App.js이 적당하겠군요. (Next.js는 _app.js)

 

다음은 Recoil의 핵심 기술인 Atom과 Selector을 알아보겠습니다.

Atom

Recoil은 Atom으로 상태 관리를 합니다. 내부 로직이 hook의 useState 함수와 동일한 API로 구현되어있습니다.

따라서, Atom 활용시 useState처럼 사용하면 됩니다.

useState와 차이점이 있다면 Atom은 상태 값을 식별하는 고유 key 속성이 존재합니다.

  
  const textState = atom({
    key: 'textState', // 키가되는 고유 문자열, selector에서 검색 할 때 사용합니다.
    default: '', // 초기값을 입력합니다.
  });

 

useRecoilState 함수에 앞에서 정의한 Atom을 인자값으로 전달하여 React의 State로 관리 할 수 있습니다.

  
  const [text, setText] = useRecoilState(textState);
    

useState와 동일하게 배열의 첫번째 인자로 state, 두번째 인자에는 dispatch 함수를 포함한 배열이 리턴됩니다.

다음은 Selector과 useRecoilValue를 살펴 보도록합시다.

 

Selector

실제로 스토어에 저장되고 가져오는 데이터는 Atom 기반이지만, 때로는 가공된 데이터를 받거나 데이터를 가공하여 저장하고 싶을 때가 있습니다. 이 때 사용하는 게 셀렉터(selector)입니다. 작성할 때는 selector 함수에 고유한 키(key)와 게터(get)와 세터(set)를 전달하여 작성합니다. 게터는 필수지만 세터는 사용하지 않아도 상관없습니다.

  
  const charCountState = selector({
    key: 'charCountState', // unique ID
    get: ({get}) => {
      const text = get(textState);

      return text.length;
    },
  });

selector에 정의 된 값은 useRecoilValue를 사용하여 얻을 수 있습니다.

  
  const count = useRecoilValue(charCountState); // text length

useRecoilValue은 상태를 설정하지 않고 값만 가져오고 싶을때 사용하는 함수입니다.

 

전체 코드

atom / selector를 이용하여 작성한 예제 코드입니다.

  
  import React from 'react';
  import {
    RecoilRoot,
    atom,
    selector,
    useRecoilState,
    useRecoilValue,
  } from 'recoil';
  
  
  const textState = atom({
    key: 'textState',
    default: '',
  });
  
  const charCountState = selector({
    key: 'charCountState',
    get: ({get}) => {
      const text = get(textState);
      return text.length;
    },
  });

  function App() {

    function CharacterCounter() {
      return (
        <div>
          <TextInput />
          <CharacterCount />
        </div>
      );
    }

    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>
      );
    }

    function CharacterCount() {
      const count = useRecoilValue(charCountState);

      return <>Character Count: {count}</>;
    }

    return (
      <RecoilRoot>
        <CharacterCounter />
      </RecoilRoot>
    );
  }

  export default App;

 

 

다양한 API 레퍼런스, 가이드, 팁은 Recoil Docs에서 확인할 수 있습니다.

 

 

 

댓글