YJzero 2023. 2. 7. 21:47

๐Ÿ“–์˜ค๋Š˜ ๋ฐฐ์šด  ๊ฒƒ

recoil

  • Atom: ๋ฐ์ดํ„ฐ ์ƒํƒœ์˜ ๋‹จ์œ„, atom์€ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ์—์„œ๋‚˜ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์œผ๋ฉฐ atom ๊ฐ’์„ ์ฝ๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์€ ์•”๋ฌต์ ์œผ๋กœ atom์„ ๊ตฌ๋…ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ atom์— ๋ณ€ํ™”๊ฐ€ ์žˆ์œผ๋ฉด ๊ตฌ๋…ํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žฌ ๋ Œ๋”๋ง๋œ๋‹ค.
  • Selector: atom์—์„œ state๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ ์ƒˆ๋กœ์šด state๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜ํ™˜ -> ํ˜„์žฌ state๋ฅผ ๊ฐ€์ง€๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๋Š” ๋ฐ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ex) todo ๋ฆฌ์ŠคํŠธ ํ•„ํ„ฐ๋ง, todo ๋ฆฌ์ŠคํŠธ ํ†ต๊ณ„ ...
const fontSizeLabelState = selector({
  key: 'fontSizeLabelState',
  get: ({get}) => {
    const fontSize = get(fontSizeState);
    const unit = 'px';

    return `${fontSize}${unit}`;
  },
});

get: get ์ธ์ž๋ฅผ ํ†ตํ•ด atoms์™€ ๋‹ค๋ฅธ selectors์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋ฅธ atoms๋‚˜ selectors์— ์ ‘๊ทผํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ข…์† ๊ด€๊ณ„๊ฐ€ ์ƒ์„ฑ -> ์ฐธ์กฐํ–ˆ๋˜ ๋‹ค๋ฅธ atoms๋‚˜ selector๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋ฉด ์ด ํ•จ์ˆ˜๋„ ๋‹ค์‹œ ์‹คํ–‰๋œ๋‹ค.

- get ํ•จ์ˆ˜๋งŒ ์ œ๊ณต๋  ๊ฒฝ์šฐ

: ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•œ RecoilValueReadonly ๊ฐ์ฒด ๋ฐ˜ํ™˜

 

- set ํ•จ์ˆ˜๋„ ์ œ๊ณต๋  ๊ฒฝ์šฐ

:์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ RecoilState ๊ฐ์ฒด ๋ฐ˜ํ™˜

 

  1. useRecoilState(): ์ƒํƒœ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. useRecoilValue(): ์ƒํƒœ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ๋งŒ ํ•œ๋‹ค. read only
  3. useSetRecoilState(): ์ƒํƒœ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜๋งŒ ์žˆ๋‹ค. write only
  4. useResetRecoilState(): ์ƒํƒœ๊ฐ’์„ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ๋ฆฌ์…‹ํ•œ๋‹ค.

 

recoil ๋น„๋™๊ธฐ ํ†ต์‹ 

- atom๊ณผ selector๋กœ ๋™๊ธฐ์  ํ†ต์‹ ํ•˜๊ธฐ

const currentUserIDState = atom({
  key: 'CurrentUserID',
  default: 1,
});

const currentUserNameState = selector({
  key: 'CurrentUserName',
  get: ({get}) => {
    return tableOfUsers[get(currentUserIDState)].name;
  },
});

function CurrentUserInfo() {
  const userName = useRecoilValue(currentUserNameState);
  return <div>{userName}</div>;
}

function MyApp() {
  return (
    <RecoilRoot>
      <CurrentUserInfo />
    </RecoilRoot>
  );
}

๋งŒ์•ฝ user์˜ ์ด๋ฆ„์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋˜์–ด ์žˆ๋‹ค๋ฉด promise๋ฅผ ๋ฆฌํ„ดํ•˜๊ฑฐ๋‚˜ async ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋งŒ ํ•ด๋„ ๋œ๋‹ค.

const currentUserNameQuery = selector({
  key: 'CurrentUserName',
  get: async ({get}) => {
    const response = await myDBQuery({
      userID: get(currentUserIDState),
    });
    return response.name;
  },
});

function CurrentUserInfo() {
  const userName = useRecoilValue(currentUserNameQuery);
  return <div>{userName}</div>;
}

propmise๊ฐ€ resolve๋˜๊ธฐ ์ „์—๋Š” ๋ฌด์—‡์„ ๋ Œ๋”ํ•  ์ˆ˜ ์žˆ์„๊ฐ€?

-> React Suspense๋ฅผ ์ด์šฉํ•ด์„œ ๋Œ€์ฒด  ui๋ฅผ ๋ Œ๋”ํ•  ์ˆ˜ ์žˆ๋‹ค.

function MyApp() {
  return (
    <RecoilRoot>
      <React.Suspense fallback={<div>Loading...</div>}>
        <CurrentUserInfo />
      </React.Suspense>
    </RecoilRoot>
  );
}

 

๋งŒ์•ฝ Suspense๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋Š” useRecoilValueLoadable() ํ›…์„ ์‚ฌ์šฉํ•ด์„œ ๋ Œ๋”๋ง ์ค‘ ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

function UserInfo({userID}) {
  const userNameLoadable = useRecoilValueLoadable(userNameQuery(userID));
  switch (userNameLoadable.state) {
    case 'hasValue':
      return <div>{userNameLoadable.contents}</div>;
    case 'loading':
      return <div>Loading...</div>;
    case 'hasError':
      throw userNameLoadable.contents;
  }
}

 

์—๋Ÿฌ๋Š” ErrorBoundary๋ฅผ ์ด์šฉํ•ด์„œ ์žก์„ ์ˆ˜ ์žˆ๋‹ค.

function MyApp() {
  return (
    <RecoilRoot>
      <ErrorBoundary>
        <React.Suspense fallback={<div>Loading...</div>}>
          <CurrentUserInfo />
        </React.Suspense>
      </ErrorBoundary>
    </RecoilRoot>
  );

 

 

 

 

๐Ÿ’ญ๋ฐฐ์šด ์ 

ํŒ€ ํ”„๋กœ์ ํŠธ์— ๋ฆฌ์ฝ”์ผ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ•ด์„œ ๋ฆฌ์ฝ”์ผ์— ๋Œ€ํ•œ ๊ณต๋ถ€๋ฅผ ์ฒ˜์Œ ์‹œ์ž‘ํ–ˆ๋‹ค. ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•ด๋ณธ ์ ์ด ์—†์–ด์„œ ์•„์ง ๊ฑฑ์ •์ด ๋งŽ์•˜๋‹ค. ์ด์ „์—๋„ context API๋งŒ ์‚ฌ์šฉํ•ด๋ดค๋Š”๋ฐ ๋ฆฌ์ฝ”์ผ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฝ์–ด๋ณด๋‹ˆ ๊ธฐ์กด ๋ฆฌ์•กํŠธ ํ›… ์‚ฌ์šฉ๊ณผ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์•„์„œ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. ๋ฐ๋ธŒ์ฝ”์Šค ๊ฐ•์˜์—์„œ ๋ฆฌ๋•์Šค๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ฒฝํ—˜ํ•ด๋ณธ ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ ์ •๋ง ์–ด๋ ต๊ณ  ์ดํ•ด๊ฐ€ ์•ˆ๋๋˜ ๊ธฐ์–ต์ด ์žˆ์–ด์„œ ๋” ๊ฑฑ์ •ํ–ˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‹ค์ œ๋กœ ๋ด๋ณด๋‹ˆ ๋ฆฌ๋•์Šค๋ณด๋‹ค ๋” ๊ฐ„๋‹จํ•˜๊ณ  ์‚ฌ์šฉ๋ฐฉ๋ฒ•๋„ ๋ณต์žกํ•˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™๋‹ค. selector๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์“ฐ๋ ค๋ฉด ๋ฆฌ์ฝ”์ผ์— ์ต์ˆ™ํ•ด์ ธ์•ผ๊ฒ ๋‹ค๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์ง€๋งŒ ์ด๊ฑด ๊ณต๋ถ€ํ•˜๊ณ  ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ต์ˆ™ํ•ด์ ธ์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค.

๋ฆฌ์ฝ”์ผ์— ๋Šฅ์ˆ™ํ•ด์ง€๋ฉด ๋‚˜์ค‘์—” ๋ฆฌ๋•์Šค๋„ ๋‹ค์‹œ ์ œ๋Œ€๋กœ ๋ฐฐ์›Œ๋ณด๊ณ  ์‹ถ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฆฌ์ฝ”์ผ์ด ์–ผ๋งˆ๋‚˜ ๊ฐ„ํŽธํ•œ์ง€ ๋” ์ฒด๊ฐ๋  ๊ฒƒ ๊ฐ™๋‹ค.