[TIL] Recoil 정리

이명진·2022년 12월 16일
0

TIL

목록 보기
3/16

전역변수 관리 리액트를 쓰던 뷰를(vue.js) 쓰던 프로젝트 규모가 커지면 거의 대부분 사용하게 된다.
여태껏 리액트로는 리덕스를 공부해봤고 vue 에서는 vuex를 직접 활용해봤다.
한때 recoil 도 뜨고 있어서 공부를 해보려고 했는데 이제서야 공부를 하고 정리해본다.

결론부터 말하자면 vue를 많이 써서 그럴지도 모르지만
vueX가 가장 쉬웠고 다음으로 recoil이 쉬운것 같다. 리덕스는 익숙치않아서 그런지 어렵다.

혼자서 사용할때는 (개인 프로젝트) recoil을 적극 활용해보고 싶다.

리코일을 설치하는 것은 생략하도록 하겠다.
Npm,yarn 으로 설치하면 된다.

React 에서 적용한 것을 개념으로 정리하였다.

RecoilRoot

설치가 다 되었다면 recoil을 사용하기 위해 app.js에 알려준다.
리코일 state를 사용하는 컴포넌트들은 RecoilRoot가 필요하다.


// app.js
import React from 'react';
import {
  RecoilRoot,
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
} from 'recoil';  

function App() {
  return (
    <RecoilRoot>   
      <Main />
    </RecoilRoot>
  );
}

Atom

아톰으로 읽으며 상태를 말한다.
아톰의 값들을 컴포넌트들이 읽는데 암묵적으로 아톰에게 구독 되어 지고 있다.
그래서 아톰이 업데이트 될때마다 컴포넌트가 리 렌더링 된다.
vueX에서는 store, 리덕스 에서도 store에 해당된다고 생각하면 된다.

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

상태를 정의할 때는 고유값인 key를 설정하고, 기본값(default)을 설정하면 된다.

사용

사용은 use 훅을 이용하여 사용할수 있다.
리액트의 useState 와 사용법이 비슷하다.

사용은 사용하고 싶은 컴포넌트로 이동해서 import해서 사용한다.

Ex) import { useRecoilState, useRecoilValue } from "recoil"; 

// useRecoilState
const [todoList, setTodoList] = useRecoilState(todoListState);

// useRecoilValue
const todoList = useRecoilValue(todoListState);

// useSetRecoilState
const setTodoList = useSetRecoilState(todoListState);

useRecoilState

useState값처럼 활용할수 있다. 배열의 첫번째 원소가 상태, 두번째 원소가 업데이트 하는 함수이다.

useRecoilValue

상태값만 필요할 경우에 사용된다.

useSetRecoilState

상태를 업데이트 하는 함수만 필요할 경우 사용된다.

왜 이렇게 useRecoilValue,useSetRecoilState 둘로 구분을 시켜놓았는지 잘 모르겠다. useRecoilState만 사용해도 될것 같은데..

useResetRecoilState

참고로 useResetRecoilState를 사용하면 atom의 state를 default값으로 reset 시킨다.
사용방법도 useResetRecoilState(아톰 이름) 으로 사용하면 된다.

selector

atom 만 으로는 비동기 처리를 할수가 없다.
Selector를 공부했을때 vue의 computed 옵션 같았다.
vueX의 getter 정도로 생각되었다. Get, set을 사용할수 있게 된다.
또한 vue의 computed 와 비슷하게 캐싱 기능이 있어서, 이미 받아왔던 정보에 대해
빠른 피드백이 가능해서 성능적으로 유리하다.

특징

  • seletor는 순수 함수 여야 한다.
  • Read-only 한 return값을 가진다.

Atom 과 비슷하게 사용되지만 다른 설정값을 가지게 된다.

//모양
Const todoSelector = selector = ({
key: ‘key’,
get: api 호출 함수 
set : set 함수 
})

Key: 고유 id, key값이다. 
Get :api call 통해 받아온 data를 return 하게 된다. 
get: async({get}) => {try{
 const {data} = await axios.get(‘’);
return data
}
catch(err){
throw err }
}

set : writeable 한 state 값을 변경할수 있는 함수를 return 한다.
단, 자기 자신을 set하려고 하면 무한 루프가 돌수 있으니 다른 selector와 atom을 set하는 로직으로 구성해야 한다.
atom 값을 두고 관련된 selector를 만들어서 set 함수로 atom값을 조절 해주면 될듯 하다.

주의

비동기 처리를 할때 아직 값이 도착하기 전이라서 렌더링 할때 ui에러가 발생하게 된다.

이럴때는 react의 suspense 로 비동기 상태를 처리 한다.

import React,{ Suspense } from 'react';
import { main } from '../components';

const App = () => {
  return(
    <RootRecoil>
      <Suspense fallback={<div>Loading...</div>}>
        <main />
      </Suspense>
    </RootRecoil>
   );
}

export default App;

두번째로 recoil에서 loadable을 지원해주었다.

loadable

당연히 recoil를 사용해서 에러가 나니 처리방법도 있을 것이다. Suspense 대신에 사용할수있다.

useRecoilValueLoadable을 이용한다.

useRecoilValueLoadable

import { useRecoilState, useRecoilValueLoadable } from 'recoil';

Import 해준다.

Loadable은 atom 이나 selector의 현재 상태를 나타내는 객체 이다.

//사용 
Const loadable = useRecoilValueLoadable(seletor); 

switch(loadable.state){
case ‘hasValue’:
	return (<html파일><html >)
case ‘loading’:
	return <Loading />;
case ‘hasError’:
	throw loadable.contents; 
 }

Switch 문을 이용해서 상태별로 보여줄 값을 렌더링 해주면 된다.

Loadable 객체
state : hasValue , hasError , loading atom 이나 selector의 상태를 말하며, 앞의 세 가지 상태를 가질 수 있다.
contents : atom이나 contents의 값을 나타내며, 상태에 따라 다른 값을 가지고 있다. hasValue 상태일 땐 value를, hasError 일 땐 Error 객체를, 그리고 loading 일 땐 Promise를 가지고 있다.

selectorFamily

외부에서 파라미터 값을 받아와서  selector에 적용해야 할 경우에 selectorFamily 를 사용한다.

// state.js 설정
const apiCall = selectorFamily({
  key: “api”,
  get: (param) => async () => {
    if (!param) return "";

    const { data } = await axios.get(
      `https://api.com/${param}`
    );
    return data;
  },
});
// 사용
import {selectorFamily} from ‘state’;
const apiCallSelectorFamily = useRecoilValue(apicall(‘param’))

이렇게 사용하면 된다.

이번에는 기초에 대해서 알아봤다. seletor부분에서 대해서 아직 헷갈리는게 많은데
직접 적용해보고 문제를 직면하다 보면 좀더 사용을 잘할수 있을것 같다.
개념 공부를 먼저 진행했다.

profile
프론트엔드 개발자 초보에서 고수까지!

0개의 댓글