๋„ˆํฌ ๋‘˜ โ— ๐Ÿ‘จ๐Ÿปโ€๐Ÿคโ€๐Ÿ‘จ๐Ÿฟ ์™œ ์„œ๋กœ ๋‹ฌ๋ผ โ“

Hugo Kimยท2021๋…„ 4์›” 13์ผ
4
post-thumbnail

์ด ๊ธ€์€ useCallback์˜ ํƒ€์ž…์„ ํŒŒํ—ค์น˜๋Š” ๊ณผ์ •์—์„œ ๋‚˜์˜จ ์˜๋ฌธ์ ์„ ํ•ด๊ฒฐํ•˜๋Š” ๊ณผ์ •์„ ๋‹ค๋ฃฌ ๊ธ€์ž…๋‹ˆ๋‹ค.
๋Œ“๊ธ€์€ ์–ธ์ œ๋‚˜ ํ™˜์˜์ž…๋‹ˆ๋‹ค! ๐Ÿ˜˜ ์žฌ๋ฐŒ๊ฒŒ ์ฝ์–ด์ฃผ์„ธ์š”! ๐Ÿ˜‰

๐Ÿš€ ์‹œ์ž‘

์ €๋Š” ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์—์„œ typescript์™€ react๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋ฅผ ์กฐํ•ฉํ•ด์„œ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๊ฐœ๋ฐœํ•˜๋˜ ์ค‘์— ์ €๋Š” ์ œ๊ฐ€ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” useCallback, useState์™€ ๊ฐ™์€ Hooks์ฝ”๋“œ๋“ค์„ ์ง์ ‘ ์ฐพ์•„๋ณด๊ฒŒ ๋์Šต๋‹ˆ๋‹ค.

๐Ÿ•ต๏ธโ€โ™‚๏ธ ์˜๋ฌธ์˜ ์‹œ์ž‘

๋จผ์ € react ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ๋“ค์–ด๊ฐ€์„œ ํด๋” ๊ตฌ์กฐ๋ฅผ ํŒŒ์•…ํ•ด๋ดค์Šต๋‹ˆ๋‹ค.
react ์ตœ์ƒ์œ„ ํด๋”๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. (ํด๋”๋ฅผ ์ œ์™ธํ•œ ํŒŒ์ผ๋“ค์€ ํฌํ•จํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.)

// react Hooks์†Œ์Šค์˜ ์œ„์น˜
๐Ÿ“ฆ react
โ””โ”€ packages
   โ””โ”€ react
      โ””โ”€ src
         โ””โ”€ ReactHooks.js

์ œ๊ฐ€ ๊ฐ€์žฅ ๊ถ๊ธˆํ–ˆ๋˜ useCallback์˜ ํƒ€์ž…์€ ์ด๋ ‡๊ฒŒ ์ •์˜๋˜์–ด์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. (์†Œ์Šค ์ฝ”๋“œ)

export function useCallback<T>(
  callback: T,
  deps: Array<mixed> | void | null,
): T {
  const dispatcher = resolveDispatcher();
  return dispatcher.useCallback(callback, deps);
}

โ„น๏ธ ์ •๋ณด
react๋Š” ์ •์  ํƒ€์ดํ•‘์„ ์œ„ํ•ด์„œ typescript๊ฐ€ ์•„๋‹Œ flow๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ๋ฅผ ๋ณด์ž๋งˆ์ž ๊ฐ€์žฅ ๋จผ์ € ๋ณด์˜€๋˜ ๊ฒƒ์€ ๋งค๊ฐœ๋ณ€์ˆ˜ deps์˜ ํƒ€์ž…์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” flow ๋ฌธ๋ฒ•์„ ์ „ํ˜€ ๋ชจ๋ฅด์ง€๋งŒ ์ฝ”๋“œ๋กœ๋งŒ ๋ดค์„ ๋•Œ deps์—๋Š” ๋ฐฐ์—ด๊ณผ null, void(undefined๋กœ ์ถ”์ •๋จ) ํƒ€์ž…๋“ค์ด ํ—ˆ์šฉ๋˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์˜€์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ œ ๊ธฐ์–ต์— ์˜ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ์—์„œ useCallback์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ deps์˜ ์ธ์ž๋กœ ๋ฐฐ์—ด์ด์™ธ์˜ ๊ฐ’์„ ๋„ฃ์—ˆ์„ ๋•Œ ํƒ€์ž… ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ ์ด ์ด์ƒํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋˜ ์ €๋Š” ๋‘ ๋ชจ๋“ˆ์ด ์‹ค์ œ๋กœ ํƒ€์ž…์ด ๋‹ค๋ฅธ์ง€ ํ™•์ธํ•ด๋ณด๊ธฐ ์œ„ํ•ด typescript ํ”„๋กœ์ ํŠธ์— react์˜ ํƒ€์ž…์„ ์ œ๊ณตํ•ด์ฃผ๋Š” @types/react ๋ชจ๋“ˆ์ด ์žˆ๋Š” ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋กœ ์ฐพ์•„๊ฐ”์Šต๋‹ˆ๋‹ค.

@types/react ๋ชจ๋“ˆ์˜ ์†Œ์Šค ์ฝ”๋“œ๋Š” DefinitelyTyped ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”๋ฐ ์ด ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” ๋ชจ๋“  typescript ํƒ€์ดํ•‘์„ ์ œ๊ณตํ•˜๋Š” ํŒจํ‚ค์ง€๋“ค์„ ์†Œ์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์†Œ์Šค ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด๋ณธ ๊ฒฐ๊ณผ, DefinitelyTyped์—์„œ ์ •์˜๋œ useCallback ํƒ€์ž… ์ •์˜๋Š” ์‹ค์ œ๋กœ react ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์—์„œ ์ •์˜๋œ ํƒ€์ž…๊ณผ ๋‹ฌ๋ž์Šต๋‹ˆ๋‹ค. (์†Œ์Šค ์ฝ”๋“œ)

 // TODO (TypeScript 3.0): <T extends (...args: never[]) => unknown>
 function useCallback<T extends (...args: any[]) => any>(callback: T, deps: DependencyList): T;
 /**

DefinetlyTyped์—์„œ ์ •์˜ํ•œ useEffect์˜ deps์˜ ํƒ€์ž…์€ react์—์„œ ์ •์˜ํ•œ ๊ฒƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋ฐฐ์—ด๋งŒ ํ—ˆ์šฉํ•˜๋Š” ํƒ€์ž…์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๐ŸŒ ํ—›์Šค์œ™

์ฒ˜์Œ ์ด ๋ถ€๋ถ„์„ ๋ฐœ๊ฒฌํ–ˆ์„ ๋•Œ flow๋กœ ์ž‘์„ฑ๋œ ํƒ€์ž…์„ typescript๋กœ ์˜ฎ๊ธฐ๋ฉด์„œ ๋ฐœ์ƒํ•œ ํœด๋จผ ์—๋Ÿฌ๋ผ๊ณ  ์ƒ๊ฐํ•ด์„œ DefinitelyTyped์— ์ด์Šˆ๋กœ ์˜ฌ๋ ธ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•ด๋‹น ์ด์Šˆ์—์„œ ๋‹ค๋ฅธ ์ปจํŠธ๋ฆฌ๋ทฐํ„ฐ๋“ค๊ณผ ์–˜๊ธฐ๋ฅผ ๋‚˜๋ˆ ๋ณธ ๊ฒฐ๊ณผ, ๊ฒฐ๋ก ์€ "๋ฌธ์ œ์—†๋‹ค"๋กœ ๋‚˜๊ฒŒ ๋์Šต๋‹ˆ๋‹ค.

์ด์œ ๋Š” DefinetlyTyped์—์„œ ์ •์˜๋œ useCallback์˜ ํƒ€์ž… ์ƒ๋‹จ์— ์ ํžŒ ์ฃผ์„์—์„œ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

// I made 'inputs' required here and in useMemo as there's no point to memoizing without the memoization key
// useCallback(X) is identical to just using X, useMemo(() => Y) is identical to just using Y.
/**
 * `useCallback` will return a memoized version of the callback that only changes if one of the `inputs`
 * has changed.
 *
 * @version 16.8.0
 * @see https://reactjs.org/docs/hooks-reference.html#usecallback
 */

useCallback๊ณผ useMemo๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•  ์ด์œ ๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์— DefinetlyTyped์—์„œ๋Š” deps ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ๋ฐฐ์—ด๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

DefinetlyTyped์—์„œ ์ •์˜๋œ ํƒ€์ž…์€ ํƒ€๊ฒŸ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ฃผ๋Š” ํŽธ์˜๋ฅผ ์œ„ํ•œ ๋ชจ๋“ˆ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํƒ€์ž…์„ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ผ๊ฐ€์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์ž์˜ ์ž…์žฅ์—์„œ ํƒ€์ž…์„ ์ •์˜ํ•˜๊ฒŒ ๋˜๋ฉด ๊ธฐ์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ •์˜๋œ ํƒ€์ž…์„ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ฅด์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ์„ ์•Œ๊ฒŒ ๋์Šต๋‹ˆ๋‹ค.

2020๋…„ 6์›” ์ดˆ์— ์•Œ๊ฒŒ ๋๊ณ  ์ •๋ฆฌ๋ฅผ ์‹œ์ž‘ํ–ˆ๋˜ ํฌ์ŠคํŠธ์˜€๋Š”๋ฐ โŒจ๏ธ
๋‹ค๋ฅธ ํฌ์ŠคํŠธ ์“ฐ๋ ค๊ณ  ๋“ค์–ด์™”๋‹ค๊ฐ€ ์ด์ œ์•ผ ๋งˆ๋ฌด๋ฆฌ,,, ๐Ÿคฆโ€โ™‚๏ธ

profile
ts์™€ react๋ฅผ ์‚ฌ๋ž‘ํ•˜๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค.

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

comment-user-thumbnail
2022๋…„ 5์›” 31์ผ

๋„ˆ๋ฌด ์ข‹์€ ๊ธ€ ์ž˜ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค!

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ