๐Ÿ“† 22.11.14 - Recoil ์•Œ์•„๋ณด๊ธฐ

๋ฒ„๋“คยท2022๋…„ 11์›” 13์ผ
0

โœจToday I Learn (TIL)

๋ชฉ๋ก ๋ณด๊ธฐ
17/62
post-thumbnail
post-custom-banner

๋ฆฌ์ฝ”์ผ์„ ์™œ์“ธ๊นŒ..?

์ด์ „์— ์“ฐ๋˜ redux, redux-toolkit ์ด ๋„ˆ๋ฌด ๋ถˆํŽธํ–ˆ๊ธฐ ๋•Œ๋ฌธ

RecoilRoot

recoil์˜ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๋ถ€๋ชจ ํŠธ๋ฆฌ ์–ด๋”˜๊ฐ€์— ๋‚˜ํƒ€๋‚˜๋Š” RecoilRoot ๊ฐ€ ์“ฐ์ž„

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

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

Atoms

์ƒํƒœ์˜ ๋‹จ์œ„์ด๋ฉฐ ์—…๋ฐ์ดํŠธ๋˜๋ฉด ์ด ๋‹จ์œ„๋ฅผ ์‚ฌ์šฉํ•œ ์ปดํฌ๋„ŒํŠธ๋Š” ์ƒˆ๋กœ์šด ๊ฐ’์„ ๋ฐ˜์˜ํ•˜์—ฌ
๋‹ค์‹œ ๋ Œ๋”๋ง

const fontSizeState = atom({
  key: 'fontSizeState',
  default: 14,
});

์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฆฌ์•กํŠธ hook์˜ usestate์ฒ˜๋Ÿผ useRecoilstate๋ผ๋Š” hook์œผ๋กœ atom์— ์žˆ๋Š” ๊ฐ’์„ state๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ณ€๊ฒฝ๋œ ๊ฐ’์„ atomํŒŒ์ผ์˜ state๋กœ ์ €์žฅํ•˜์—ฌ ๊ทธ ์ €์žฅ๋œ ๊ฐ’์„ ๋‹ค๋ฅธ Components๋กœ ์šฉ์ดํ•˜๊ฒŒ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

function FontButton() {
  const [fontSize, setFontSize] = useRecoilState(fontSizeState);
  return (
    
    // setFontSize์— ๋ณ€ํ™”๋ฅผ ์ค˜์„œ atom์˜ state ๊ฐ’์„ ๋ณ€ํ™”ํ•˜๊ฒŒ ๋˜๊ณ , ๊ทธ์™€ ๋™์‹œ์— ๊ฐ™์€ state๊ฐ’์„ ์“ฐ๋˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ’๋„ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค.
    <button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>
      Click to Enlarge
    </button>
  );
}

๋‹ค๋ฅธ ์˜ˆ )

const todoListState = atom({
  key: 'todoListState',
  default: [],
});
function TodoItemCreator() {
  const [inputValue, setInputValue] = useState('');
  const setTodoList = useSetRecoilState(todoListState);

  const addItem = () => {
    setTodoList((oldTodoList) => [
      ...oldTodoList,
      {
        id: getId(),
        text: inputValue,
        isComplete: false,
      },
    ]);
    setInputValue('');
  };

  const onChange = ({target: {value}}) => {
    setInputValue(value);
  };

  return (
    <div>
      <input type="text" value={inputValue} onChange={onChange} />
      <button onClick={addItem}>Add</button>
    </div>
  );
}

// ๊ณ ์œ ํ•œ Id ์ƒ์„ฑ์„ ์œ„ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ
let id = 0;
function getId() {
  return id++;
}

Selectors

atoms๋‚˜ ๋‹ค๋ฅธ selectors๋ฅผ ๋ฐ›์•„๋“ค์ด๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜. ์ด์ „์— vuex์—์„œ ์ผ๋˜ mutations๋ž‘ ๋งŽ์ด ๋‹ฎ์•„ ์žˆ๋Š” ๋“ฏ ํ•˜๋‹ค.

const todoListFilterState = atom({
  key: 'todoListFilterState',
  default: 'Show All',
});

const filteredTodoListState = selector({
  key: 'filteredTodoListState',
  get: ({get}) => {
    const filter = get(todoListFilterState);
    const list = get(todoListState);

    switch (filter) {
      case 'Show Completed':
        return list.filter((item) => item.isComplete);
      case 'Show Uncompleted':
        return list.filter((item) => !item.isComplete);
      default:
        return list;
    }
  },
});

ํ•˜๋‚˜์˜ selector์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•˜๋‹ค๊ณ  ์‚ฌ๋ฃŒ.

atom ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด get ํ•จ์ˆ˜๋ฅผ, selector๋ฅผ ํ™œ์šฉํ•˜๋ ค๋ฉด, useRecoilValueํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ

profile
ํƒœ์–ด๋‚œ ๊น€์— ๋งŽ์€ ๊ฒฝํ—˜์„ ํ•˜๋ ค๊ณ  ์•„๋“ฑ๋ฐ”๋“ฑ ์• ์“ฐ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž
post-custom-banner

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