[React] State Management - Recoil 사용하기

김지원·2023년 1월 18일
0

Frontend

목록 보기
12/27

❓ What is a State Management?

📌Recoil, Redux를 사용한다.

State management는 왜 필요한가?

State Management 없이 Toggle을 구현해보면,
ThemeProviderApp() 로 옮겨주고, useState를 사용하여 구현할 수 있다.

👉 다시 말해, Props 가 traveling 하는 상태라고 할 수 있다.

function App() {
  const [isDark, setIsDark] = useState(false);
  const toggleDark = () => setIsDark((current)=> !current);
  return (
    <>
    <ThemeProvider theme={isDark ? darkTheme: lightTheme}>
      <button onClick={toggleDark}>Toggle Mode</button>
    </ThemeProvider>
    </>
  );
}

위처럼 toggleDark를 Component 간 계속 전달해줘야 한다!!!

App (isDark, modifierFn)
=> Router => Coins (modifier)
=> Router => Coin => Chart (isDark)

이것이 바로 Global State이다.

Global State: Application 전체에서 공유되는 state

  • Global State는 어플리케이션이 무언가를 인지해야 할 때 사용한다.
  • 예를 들어 특정 value (여기서는 isDark)에 접근해야 할 때, 특정 value를 수정해야 할 때(여기서는 toggleDark) 사용한다.

Application 전체에서 무언가를 공유해야 하는 경우?

  • User 의 로그인 여부에 따라 보여줄 component가 달라질 것

❗State Management를 사용한다면?

// state management 없이
isDark: App -> Router -> Coin -> Chart

// state management 사용
Header -> (isDark) <- Chart

이 때 Recoilstate를 어떤 Atom에 넣어두고, 이 Atom에 접근할 수 있도록 하는 것이 핵심이다.

global state를 application의 분리된 공간, Atom에서 관리할 수 있도록 해준다.

이처럼 state가 ❗특정 Component에 종속되지 않도록 해준다.
따라서 component는 부모의 부모의 부모의 ... 로부터 value를 받아올 필요가 없다.

👉 Traveling prop => Listening atom

💡Recoil이란?

Recoil 은 ReactJS에서 사용할 수 있는 state management 라이브러리이다. 링크

npm install recoil
  1. 먼저 새로운 atom 파일을 만든다.
import { atom } from "recoil";

export const isDarkAtom = atom({
    key: "isDark",
    default: false
})
  1. 그리고 위 atom을 사용할 component에서 ✨useRecoilValue 함수를 사용하면 된다.
function Chart({coinId}: ChartProps) {
    const isDark = useRecoilValue(isDarkAtom);
  ...
}
  1. atom을 수정하기 위해서는 ✨useSetRecoilState 함수를 사용한다.
const setDarkAtom = useSetRecoilState(isDarkAtom);
const toggleDarkAtom = () => setDarkAtom((prev)=>!prev);

...
<button onClick={toggleDarkAtom}>Toggle Mode</button>
...
  • useRecoilValueuseSetRecoilState 를 한 번에 사용하려면 useRecoileState 사용하기
const [value, modFn] = useRecoilState(toDoState);
// const value = useRecoilValue(toDoState);
// const modFn = useSetRecoilState(toDoState);

💡Recoil - Selectors

A 👉selector👈 represents a piece of 📌derived state📌. You can think of derived state as the output of passing state to a pure function that derives a 📌new value from the said state📌. 공식문서

atom의 output을 변형하려면?
👉selector👈state를 가지고 새로운 뭔가(📌derived state📌)를 return한다.

export const toDoSelector = selector({
    key: "toDoSelector",
    get: ({get})=>{
        const toDos = get(toDoState)
        return toDos.length;
    },
});

useRecoilValue를 이용해서 atom의 output, selector의 output을 얻을 수 있다.

📌 Set Selectors

두 개의 atom을 만드는 대신 하나의 state를 가지고 2개의 property를 가지는 selector을 사용할 수 있다.

selector가 활용될 수 있는 경우는,

  • 여러 개의 각각의 atom을 가져오는 하나의 selector
  • 다른 여러 개의 atom을 설정하는 selector

💡 options - get

  1. selector가 state을 가져와서 수정된 값을 돌려주기
export const toDoSelector = selector({
    key: "toDoSelector",
    get: ({get})=>{
        const toDos = get(toDoState);
        const category = get(categoryState);
        return toDos.filter((toDo)=> toDo.category === category);
    },
});

💡 options - set

  1. set property로 state를 수정하기
    selector의 atom의 값을 설정할 수 있다.
export const hourSelector = selector<number>({
    key: "hours",
    get: ({get}) => {
        const minutes = get(minuteState);
        return minutes/60;
    },
    set: ({set}, newValue) => {
        const minutes = Number(newValue) * 60;
        set(minuteState, minutes);
    }
});

🪄 useRecoilState()

const [first, second] = useRecoilState(hourSelector);
  • 첫 번째 argument: atom의 값 또는 selector의 get 함수
  • 두 번째 argument: atom을 수정하는 함수 또는 set property를 실행시키는 함수
profile
Make your lives Extraordinary!

0개의 댓글