๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

React

[ React / Recoil ] React์˜ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Recoil์˜ effects ์‚ฌ์šฉํ•˜๊ธฐ.

๋‚˜๋Š” ๋ณดํ†ต react ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด ๊ฐ„๋‹จํ•œ ์ƒํƒœ ๊ด€๋ฆฌ๋“ค์€ ๋Œ€๋ถ€๋ถ„ recoil์„ ํ†ตํ•ด ํ•˜๋Š”๋ฐ

์ด๋ฒˆ์— recoil์˜ ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•ด ๋” ์„œ์น˜๋ฅผ ํ•˜๋‹ค๊ฐ€ Atom Effects์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค.

 

Recoil ๊ณต์‹ ํŽ˜์ด์ง€์˜ Atom Effects ์„ค๋ช…์€ ์•„๋ž˜ ๋งํฌ๋ฅผ ํ†ตํ•ด ์ฐธ๊ณ ํ•˜๋ฉด ๋œ๋‹ค.

atom effects - recoil

 

 

 

recoil ๊ณต์‹ ํŽ˜์ด์ง€์—์„œ ์†Œ๊ฐœํ•˜๋Š” atom effects๋Š” ๋ถ€์ˆ˜ํšจ๊ณผ๋“ค์„ ๊ด€๋ฆฌํ•˜๊ณ  Recoil์˜ atom์„ ์ดˆ๊ธฐํ™”ํ•˜๊ฑฐ๋‚˜ ๋™๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” API๋ผ๊ณ  ์„ค๋ช…ํ•œ๋‹ค.

 

Atom Effects

- ์ƒํƒœ ์ง€์†์„ฑ

- ์ƒํƒœ ๋™๊ธฐํ™”

- ํžˆ์Šคํ† ๋ฆฌ ๊ด€๋ฆฌ

- ๋กœ๊น…

 

๋“ฑ์— ์œ ์šฉํ•˜๊ณ  React Effects์™€๋„ ์œ ์‚ฌํ•˜์ง€๋งŒ Atom Effects๋Š” atom์„ ์ •์˜ํ•  ๋•Œ atom ์ •์˜์˜ ์ผ๋ถ€๋กœ ์ •์˜ ๋œ๋‹ค๊ณ  ํ•œ๋‹ค.

์ฆ‰ effects์™€ atom ์ •์˜๋ฅผ ํ•จ๊ป˜ ๋ฐฐ์น˜ํ•˜๊ฒŒ ํ•˜๋Š” ๋™๊ธฐํ™” ํšจ๊ณผ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

 

Atom Effects๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋ฆฌ์•กํŠธ์˜ useEffect()๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์œผ๋‚˜ atom์˜ ์ง‘ํ•ฉ์€ ๋ฆฌ์•กํŠธ ์ปจํ…์ŠคํŠธ์˜ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋˜๋ฉฐ, ํŠนํžˆ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ atom์˜ ๊ฒฝ์šฐ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ํšจ๊ณผ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๊ณ  ์ฒ˜์Œ์— atom ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ•˜๊ฑฐ๋‚˜ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง(SSR)๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ๋  ์ˆ˜๋„ ์—†์–ด์„œ atom effects๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์•ˆ๋‚ดํ•œ๋‹ค.

 

 

 

 

Atom Effects ์ •์˜

type AtomEffect<T> = ({
  node: RecoilState<T>, // A reference to the atom itself
  storeID: StoreID, // ID for the <RecoilRoot> or Snapshot store associated with this effect.
  trigger: 'get' | 'set', // The action which triggered initialization of the atom

  // Callbacks to set or reset the value of the atom.
  // This can be called from the atom effect function directly to initialize the
  // initial value of the atom, or asynchronously called later to change it.
  setSelf: (
    | T
    | DefaultValue
    | Promise<T | DefaultValue> // Only allowed for initialization at this time
    | ((T | DefaultValue) => T | DefaultValue),
  ) => void,
  resetSelf: () => void,

  // Subscribe to changes in the atom value.
  // The callback is not called due to changes from this effect's own setSelf().
  onSet: (
    (newValue: T, oldValue: T | DefaultValue, isReset: boolean) => void,
  ) => void,

  // Callbacks to read other atoms/selectors
  getPromise: <S>(RecoilValue<S>) => Promise<S>,
  getLoadable: <S>(RecoilValue<S>) => Loadable<S>,
  getInfo_UNSTABLE: <S>(RecoilValue<S>) => RecoilValueInfo<S>,
}) => void | () => void; // Optionally return a cleanup handler

 

Atom Effects๋Š” effects ์˜ต์…˜์„ ํ†ตํ•ด atoms์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ  ๊ฐ๊ฐ์˜ atom์€ ์ดˆ๊ธฐํ™”๋  ๋•Œ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ํ˜ธ์ถœ๋˜๋Š” atom effect ํ•จ์ˆ˜๋“ค์˜ ๋ฐฐ์—ด์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

 

atom effects์˜ ์ดˆ๊ธฐํ™”๋ฅผ ์œ„ํ•œ cleanup ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

 

 

 

 

๋‚ด๊ฐ€ ํ•˜๊ณ ์‹ถ์—ˆ๋˜ atom effects์˜ ๊ธฐ๋Šฅ์€ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€ ์ง€์†์„ฑ ํŒŒํŠธ์˜€๋Š”๋ฐ, ์•„๋ž˜์™€ ๊ฐ™์€ ์„ค๋ช…์ด ์ ํ˜€์žˆ์—ˆ๋‹ค.

Atom Effects๋Š” atom ์ƒํƒœ๋ฅผ ๋ธŒ๋ผ์šฐ์ € ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. localStorage ๋Š” ๋™๊ธฐ์‹์ด๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ async/await ํ˜น์€ Promise ์—†์ด ์ง์ ‘ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

์•„๋ž˜๋Š” Atom Effects๋ฅผ ์ด์šฉํ•˜์—ฌ localStorage์™€ ๋™๊ธฐํ™” ๋ฐ ์ดˆ๊ธฐํ™” ์ž‘์—…์„ ํ•ด์ฃผ๋Š” ์ฝ”๋“œ์ด๋‹ค.

const localStorageEffect = key => ({setSelf, onSet}) => {
  const savedValue = localStorage.getItem(key)
  if (savedValue != null) {
    setSelf(JSON.parse(savedValue));
  }

  onSet((newValue, _, isReset) => {
    isReset
      ? localStorage.removeItem(key)
      : localStorage.setItem(key, JSON.stringify(newValue));
  });
};

const currentUserIDState = atom({
  key: 'CurrentUserID',
  default: 1,
  effects: [
    localStorageEffect('current_user'),
  ]
});

์ด๋Ÿฐ ์‹์œผ๋กœ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€ ์ดํŽ™ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

์‹ค์ œ๋กœ refreshToken์„ ์–ป์–ด์„œ atom์— setRecoilValue๋ฅผ ํ†ตํ•ด token์„ ์ €์žฅํ•˜๋‹ˆ ์ž๋™์œผ๋กœ localStorageEffect ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ ์ •์ƒ์ ์œผ๋กœ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค!

 

 

Recoil์€ ๋‹ค๋ฅธ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์— ๋น„ํ•ด ๊ฐ€๋ณ๊ณ  ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์ตœ์†Œํ•œ์˜ ๊ธฐ๋Šฅ๋“ค๋งŒ ์ œ๊ณตํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์—ˆ๋Š”๋ฐ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ๋“ค์„ ๊ผผ๊ผผํžˆ ๋ณด์ง€ ์•Š์€ ๋‚˜์˜ ๋ฌด์ง€ํ•œ ํŒ๋‹จ์ด์—ˆ๋‹ค.ใ…‹ใ…‹ ์—ญ์‹œ ๊ฐ€๋ณ๊ฒŒ ํ›‘์–ด๋ณด๊ณ  ํŒ๋‹จํ•˜๋ฉด ์•ˆ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋˜ ํ•œ ๋ฒˆ ๋Š๊ผˆ๋‹ค.