[React] Recoil

๋ฐ•์†Œ์ •ยท2023๋…„ 12์›” 7์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
15/26
post-thumbnail

Recoil์ด๋ž€?๐Ÿ˜Š

Recoil์€ React๋ฅผ ์œ„ํ•œ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.

Atom๐Ÿ‘


Atom ์ •์˜

Atom์€ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ ๊ณต์œ ๋˜๋Š” ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ด๋Ÿฌํ•œ Atom์ด ์—…๋ฐ์ดํŠธ ๋  ๊ฒฝ์šฐ ํ•ด๋‹น Atom์— ์˜ํ–ฅ์ด ์žˆ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ์ƒํƒœ๊ฐ€ ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ ๋ฆฌ๋ด๋” ๋œ๋‹ค.

์‚ฌ์šฉํ•˜๊ธฐ์— ์•ž์„œ Atom์„ ์ •์˜ํ•ด์ค„ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

// atoms.js
import { atom } from 'recoil';

export const counterState = atom({
  key: 'counterState', 
  default: 0,    
});

Atom ์‚ฌ์šฉํ•˜๊ธฐ(useRecoilState)

์ •์˜ํ•œ Atomd์„ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ useRecoilState์„ ์ด์šฉํ•˜์—ฌ ์ƒํƒœ๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋‹ค.

// CounterComponent.js
import React from "react";
import { useRecoilState } from "recoil";
import { counterState } from "./atoms";

function CounterComponent() {
  const [counter, setCounter] = useRecoilState(counterState);

  const increaseCounter = () => setCounter(counter + 1);
  const decreaseCounter = () => setCounter(counter - 1);

  return (
    <div>
      <p>Counter: {counter}</p>
      <button onClick={increaseCounter}>Increase</button>
      <button onClick={decreaseCounter}>Decrease</button>
    </div>
  );
}

export default CounterComponent;

  • RecoilRoot

    CounterComponent๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” RecoilRoot ๋‚ด๋ถ€์— ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค.
    (๋‹ค์Œ ์‚ฌ์ง„์€ Increase button์„ 1๋ฒˆ ํด๋ฆญํ•œ ์ƒํƒœ์ด๊ณ , ์ดˆ๊ธฐ ๊ฐ’์€ 0์ด๋‹ค.)
import React from "react";
import { RecoilRoot } from "recoil";
import CounterComponent from "./component/CounterComponent";

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

export default App;

  • ๋งŒ์•ฝ RecoilRoot๋กœ ๊ฐ์‹ธ์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ?

    ๋‹ค์Œ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด Recoil์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋“œ์‹œ RecoilRoot๋กœ ๊ฐ์‹ธ์ ธ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜์˜จ๋‹ค.
    import React from "react";
    import { RecoilRoot } from "recoil";
    import CounterComponent from "./component/CounterComponent";

    function App() {
      return (
          <CounterComponent />
      );
    }

    export default App;

Atom ์‚ฌ์šฉํ•˜๊ธฐ(useRecoilValue)

useRecoilState์™€ ๋‹ฌ๋ฆฌ useRecoilValue๋Š” ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜์—†์ด 'Atom' ๊ฐ’๋งŒ ๋ฐ›๋Š”๋‹ค.

// DisplayComponent.js
import React from "react";
import { useRecoilValue } from "recoil";
import { counterState } from "./atoms";

function DisplayComponent() {
  const counter = useRecoilValue(counterState);

  return (
    <div>
      <p>Counter Value: {counter}</p>
    </div>
  );
}

export default DisplayComponent;
  • RecoilRoot

    ์ƒํƒœ์˜ ๋ณ€ํ™” ์—†์ด Atom ๊ฐ’๋งŒ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ ์‚ฌ์ง„๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.
    ({counter}์˜ ๊ฐ’์ด 0์ธ ์ด์œ ๋Š” atoms.js์—์„œ Atom์„ ์ •์˜ํ–ˆ์„ ๋•Œ dafault ๊ฐ’์„ 0์œผ๋กœ ์„ค์ •ํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ)
    import React from "react";
    import { RecoilRoot } from "recoil";
    import DisplayComponent from "./component/DisplayComponent";

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

    export default App;

Selector๐Ÿ‘


Selector ์ •์˜

Atom์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด atom์˜ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
Atom์˜ ๊ฐ’์ด ์ตœ์‹ ํ™”๋˜๋ฉด ์ž๋™์œผ๋กœ selector์˜ ๊ฐ’๋„ ์ตœ์‹ ํ™”ํ•˜๋ฏ€๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ์— ๊ฐ„ํŽธํ•˜๋‹ค.

import { atom, selector } from "recoil";

export const counterState = atom({
  key: "counterState",
  default: 1,
});

export const doubleCounterState = selector({
  key: "doubleCounterState",
  get: ({ get }) => {
    const counter = get(counterState);
    return counter * 2;
  },
});

Selector ์‚ฌ์šฉํ•˜๊ธฐ(useRecoilValue)

import React from "react";
import { useRecoilValue } from "recoil";
import { doubleCounterState } from "./atoms";

function CounterWithDoubleComponent() {
  const doubleCounter = useRecoilValue(doubleCounterState);

  return (
    <div>
      <p>Double Counter: {doubleCounter}</p>
    </div>
  );
}

export default CounterWithDoubleComponent;
  • RecoilRoot

import React from "react";
import { RecoilRoot } from "recoil";
import CounterWithDoubleComponent from "./component/CounterWithDoubleComponent";
import CounterComponent from "./component/CounterComponent";

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

export default App;

๐Ÿ‘‰ ์•„์ง๊นŒ์ง€ Selector์€ useRecoilState๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ณ , useRecoilValue๋ฅผ ์ด์šฉํ•ด์„œ ๋ฆฌํ„ด๋˜๋Š” ๊ฐ’๋งŒ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. (2021)

์„ค์น˜๐Ÿ˜Ž

  • React ์„ค์น˜

	npx create-react-app .
  • Recoil ์„ค์น˜

	npm install recoil

๐Ÿ’ก

  • ๋žœ๋”๋ง & ๋ฆฌ๋žœ๋”๋ง

    ๋žœ๋”๋ง: UI๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ• ์ง€, ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ์ž‘์—…์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
    ๋ฆฌ๋žœ๋”๋ง: ๋žœ๋”๋ง ์ดํ›„ ํŠน์ • ์กฐ๊ฑด์ด ๋ฐœํ–‰ํ•˜์—ฌ ๋‹ค์‹œ ๋ Œ๋”๋ง์„ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€