Frontend/TypeScript

[ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ(TypeScript) ] ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋‚ด๋ถ€์—์„œ ์ค‘๋ณต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜ ๋ฆฌํŒฉํ† ๋งํ•˜๊ธฐ

YWTechIT 2022. 9. 19. 06:43
728x90

๐Ÿ“ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ค‘๋ณต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜ ๋ฆฌํŒฉํ† ๋ง ํ•˜๊ธฐ

React๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„๋‹Œ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ onClick์‹œ ๋™์ž‘ํ•˜๋Š” handlerํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๋‹ค ๋ณด๋ฉด, handler ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ์กฐ๊ฑด์œผ๋กœ ๋ถ„๊ธฐํ•  ๋•Œ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์ค‘๋ณต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์€ ์• ์ž์ผ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•์˜ ํ•˜๋‚˜์ธ ํŽ˜์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Pair programming)์œผ๋กœ ์ž‘์—…์„ ํ•˜๋‹ค๊ฐ€ ๋„ค๋น„๊ฒŒ์ดํ„ฐ(navigator)๋ฅผ ๋งก๊ณ  ๊ณ„์‹  ํ—ค์ผ๋ฆฌ๊ฐ€ ๋ฐœ๊ฒฌํ•ด์ฃผ์‹  ์ผ€์ด์Šค์ธ๋ฐ, ์กฐ๊ฑด์— ์˜ํ•ด ์ธ์ž ๊ฐ’์ด ๋ฐ”๋€Œ์–ด๋„ ํ•จ์ˆ˜๋Š” ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ๋•Œ ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜๋กœ ํ•ฉ์ณค๋Š”๊ฐ€์— ๋Œ€ํ•ด ์ž‘์„ฑํ•ด๋ณด๋ ค ํ•œ๋‹ค. ํ•˜๋‹จ ์ฝ”๋“œ๋Š” ๋ฆฌํŒฉํ† ๋ง ์ „ clickEventHandler ํ•จ์ˆ˜์˜ ์ฝ”๋“œ์ด๋‹ค.

 

์ด ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผํ•˜๋Š”๋ฐ ์—๋Ÿฌ๋Š” ์—†์ง€๋งŒ ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ค„๋ณธ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๊ฐ™์€ ์—ญํ• ์„ ํ•˜์ง€๋งŒ ์ค‘๋ณต๋œ ์ฝ”๋“œ๋ฅผ ๋ดค๋‹ค๋ฉด ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๊ณ  ์‹ถ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋ฟœ๋ฟœ ํ•  ๊ฒƒ์ด๊ณ  ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐœ์„ ํ–ˆ๋Š”์ง€์— ๋Œ€ํ•ด ์ž‘์„ฑํ•ด๋ดค๋‹ค. ๋ฆฌํŒฉํ† ๋ง์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๊ณ , ๊ฐœ๋ฐœ์ž๋งˆ๋‹ค ๊ทธ ๋ฐฉ๋ฒ•์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ๋ฐฉ๋ฒ•๋„ ์žˆ๊ตฌ๋‚˜๋ผ๋Š” ๊ฒƒ์— ์ดˆ์ ์„ ๋งž์ถฐ์ฃผ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ๋‹ค.(๋Œ“๊ธ€์— ํ”ผ๋“œ๋ฐฑ์„ ๋‹ฌ์•„์ฃผ์‹œ๋Š” ๊ฒƒ๋„ ๋ฌผ๋ก  ํ™˜์˜์ด๋‹ค.) ๊ทธ๋Ÿผ ์ดˆ๊ธฐ ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์ž.(๋ฐ”์˜์ง€ ์•Š๋‹ค๋ฉด ์ง์ ‘ ๋ฆฌํŒฉํ† ๋งํ•ด๋ณด์ž.)

728x90
// AS-IS
function clickEventHandler(
  onLinkClick?: LinkEventHandlerType,
  onImageClick?: ImageEventHandlerType,
): ImageEventHandlerType {
  return (event, image) => {
    if (image.link && image.link.hash && onLinkClick) {
      return onLinkClick(event, {
         href: `#${image.link.hash}`,
      })
    }
    if (image.link && image.link.href && onLinkClick) {
      return onLinkClick(e, {
          href: image.link.href,
        })
    } else if (onImageClick) {
      return onImageClick(event, image)
    }
  }
}

์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์ฐพ์•˜๋Š”๊ฐ€? ๋‚˜๋Š” 7๋ฒˆ๊ณผ 12๋ฒˆ์˜ image.link && onLinkClick ์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜๋Š” ๊ฒƒ์„ ์ฐพ์•˜๋‹ค. ๋” ์ข‹์€ ๋ฐฉ๋ฒ•๋„ ์žˆ๊ฒ ์ง€๋งŒ image.link && onLinkClick๋ฅผ ํ•˜๋‚˜์˜ ์กฐ๊ฑด๋ฌธ์œผ๋กœ ํ•ฉ์ณ๋ณด์•˜๋‹ค.

function clickEventHandler(
  onLinkClick?: LinkEventHandlerType,
  onImageClick?: ImageEventHandlerType,
): ImageEventHandlerType {
  return (event, image) => {
    if (image.link && onLinkClick) {
      if (image.link.hash) {
        return onLinkClick(event, {
          href: `#${image.link.hash}`,
        })
      }

      if (image.link.href) {
        return onLinkClick(e, {
          href: image.link.href,
        })
      } else if (onImageClick) {
        return onImageClick(event, image)
      }
    }
  }
}

์ด๋ ‡๊ฒŒ ํ•˜๋‚˜์˜ ์กฐ๊ฑด๋ฌธ์œผ๋กœ ํ•ฉ์น˜๊ณ  ๋‚ฌ๋Š”๋ฐ, ๋‹ค์Œ์—” ์–ด๋–ป๊ฒŒ ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉด ์ข‹์„๊นŒ?! ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ, ๋‚˜๋Š” onLinkClick์˜ ์ค‘๋ณต ์‚ฌ์šฉ์„ ์ค„์ด๊ณ  ์‹ถ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ onLinkClick ํ•จ์ˆ˜๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด image.link.hash์™€ image.link.href๊ฐ’์„ ์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋กœ ๋”ฐ๋กœ ๋นผ๋‚ด์–ด ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ–ˆ๋‹ค.

function clickEventHandler(
  onLinkClick?: LinkEventHandlerType,
  onImageClick?: ImageEventHandlerType,
): ImageEventHandlerType {
  return (event, image) => {
    if (image.link && onLinkClick) {
      const href = image.link.hash ? `#${image.link.hash}` : image.link.href
      return onLinkClick(event, { href })
    } else if (onImageClick) {
      return onImageClick(event, image)
    }
  }
}

๋งˆ์ง€๋ง‰์œผ๋กœ ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆ๋ฌด๋ฆฌํ–ˆ๋‹ค. 7๋ฒˆ ๋ผ์ธ์—์„œ href: prevHref๋กœ ์ž‘์„ฑํ•œ ์ด์œ ๋Š” 8๋ฒˆ ๋ผ์ธ์—์„œ href ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•ด์•ผ onLinkClick ํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋ฅผ { href: href } ๋Œ€์‹  { href }๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

function clickEventHandler(
  onLinkClick?: LinkEventHandlerType,
  onImageClick?: ImageEventHandlerType,
): ImageEventHandlerType {
  return (event, image) => {
    if (image.link && onLinkClick) {
      const { hash, href: prevHref } = image.link
      const href = hash ? `#${hash}` : prevHref
      return onLinkClick(event, { href })
    } else if (onImageClick) {
      return onImageClick(event, image)
    }
  }
}

๊ฒฐ๋ก ์ ์œผ๋กœ ๋ฆฌํŒฉํ† ๋ง ์ „๊ณผ ํ›„์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

// AS-IS
function clickEventHandler(
  onLinkClick?: LinkEventHandlerType,
  onImageClick?: ImageEventHandlerType,
): ImageEventHandlerType {
  return (event, image) => {
    if (image.link && onLinkClick) {
      if (image.link.hash) {
        return onLinkClick(event, {
          href: `#${image.link.hash}`,
        })
      }

      if (image.link.href) {
        return onLinkClick(e, {
          href: image.link.href,
        })
      } else if (onImageClick) {
        return onImageClick(event, image)
      }
    }
  }
}

// TO-BE
function clickEventHandler(
  onLinkClick?: LinkEventHandlerType,
  onImageClick?: ImageEventHandlerType,
): ImageEventHandlerType {
  return (event, image) => {
    if (image.link && onLinkClick) {
      const { hash, href: prevHref } = image.link
      const href = hash ? `#${hash}` : prevHref
      return onLinkClick(event, { href })
    } else if (onImageClick) {
      return onImageClick(event, image)
    }
  }
}

์ด๋ ‡๊ฒŒ ์ค‘๋ณต ์‚ฌ์šฉ๋˜์–ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๊ธธ์–ด์ง„ ๋„ˆ์ €๋ถ„ํ•œ ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•ด๋ดค๋‹ค. ์ด๋ฒˆ ๋ฆฌํŒฉํ† ๋ง์˜ ๊ทœ๋ชจ๋Š” ํฌ์ง„ ์•Š์ง€๋งŒ ์ž‘์€ ์ฝ”๋“œ๋ถ€ํ„ฐ ๋ฆฌํŒฉํ† ๋งํ•˜๋‹ค๋ณด๋ฉด ์–ธ์  ๊ฐ€ ๊ทœ๋ชจ๊ฐ€ ํฐ ์ฝ”๋“œ๋„ ๊ธˆ๋ฐฉ ๋ฆฌํŒฉํ† ๋ง ํ•  ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ..?๋ผ๋Š” ์ƒ๊ฐ์„ ํ•˜๋ฉฐ ์ด๋ฒˆ ํฌ์ŠคํŒ…์„ ๋งˆ์นœ๋‹ค.

 

Reference

  1. ํŽ˜์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ์œ„ํ‚ค๋ฐฑ๊ณผ
  2. ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น - MDN
๋ฐ˜์‘ํ˜•