[TypeScript] ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ
728x90

Today, What I learned?

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฒ€์ƒ‰๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ๋˜ ๊ณผ์ •์„ ๊ธฐ๋กํ•œ๋‹ค.

์™„์„ฑํ•œ ๊ธฐ๋Šฅ์€ ์ด๋ ‡๋‹ค.

์ด๋ฏธ์ง€๊ฐ€ ๋„ˆ๋ฌด ์ž‘์ง€๋งŒ!.. ํ•œ๊ธ€, ์˜์–ด ๋Œ€๋ฌธ์ž, ์†Œ๋ฌธ์ž๊ฐ€ ๋ชจ๋‘ ๊ฒ€์ƒ‰์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.

 

๊ฒ€์ƒ‰๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์•ž์„œ์„œ, ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์˜ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์€ ์•ž์„œํ–ˆ๋˜ ํ”„๋กœ์ ํŠธ์™€๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅธ ์„ฑ๊ฒฉ์˜ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด ๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๋Š” ์ € ๋•Œ 20๋ช… ์ •๋„์˜ ์•„ํ‹ฐ์ŠคํŠธ ๋ชฉ๋ก์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๊ณ , (๋ฉฐ์น  ์‚ฌ์ด ์กฐ๊ธˆ ๋” ๋Š˜์—ˆ์Œ)

์–ด๋–ค ๋‹จ์–ด์™€ ์ผ์น˜ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์ฐพ์•„๋‚ด๊ธฐ ๋ณด๋‹ค๋Š”,

ํ•ด๋‹น ์•„ํ‹ฐ์ŠคํŠธ์˜ ์œ ํŠœ๋ธŒ ๋ชฉ๋ก ํŽ˜์ด์ง€๋กœ ๋ฐ”๋กœ ๋„˜์–ด๊ฐ€๋Š” ๊ฒŒ ๋” ์ข‹์ง€ ์•Š์„๊นŒ? ์‹ถ์–ด์„œ ๊ทธ๋ ‡๊ฒŒ ํ•ด๋ณด๊ธฐ๋กœ!..

 

 

๊ฒ€์ƒ‰์ฐฝ ์™ธ๋ถ€ ํด๋ฆญ ๊ฐ์ง€

์ด๋ฒˆ์—๋Š” ์•„์ด์ฝ˜์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ๊ฒ€์ƒ‰์ฐฝ์ด ๋‚˜์˜ค๋Š” UI๋ฅผ ๊ตฌํ˜„ํ•ด ๋ณด์•˜๋‹ค.

ํ—ค๋” ์•ˆ์˜ ๋‹ค๋ฅธ ์˜์—ญ์„ ํด๋ฆญํ•˜๋ฉด ๊ฒ€์ƒ‰์ฐฝ์ด ๋‹ซํžˆ๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์‰ฝ์ง€ ์•Š์•˜๋‹ค.

์šฐ์„  ํ—ค๋”์—์„œ๋Š” ๊ฒ€์ƒ‰์ฐฝ์œผ๋กœ setState์™€ useRef์˜ ref๋ฅผ props๋กœ ๋‚ด๋ ค์ค€๋‹ค.

  {isLoggedIn && (
        <Icons>
          {showSearchInput && (
            <SearchInput
              inputRef={searchInputRef}
              setShowSearchInput={setShowSearchInput}
            />
          )}
          <SearchIcon onClick={() => setShowSearchInput(true)} />
        ...
        </Icons>
      )}

ํด๋ฆญ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๋Š” ํ•จ์ˆ˜๋Š” ์•„๋ž˜ ๋ถ€๋ถ„์ด๋‹ค.

  // ๊ฒ€์ƒ‰์ฐฝ ์™ธ๋ถ€ ํด๋ฆญ ์—ฌ๋ถ€ ํŒ๋‹จ
  const clickOutside = (e: any) => {
    if (
      searchInputRef.current &&
      !searchInputRef.current.contains(e.target as Node)
    ) {
      setShowSearchInput(false);
    }
  };

ref.current์—๋Š” Input์ฐฝ์— ํ•ด๋‹นํ•˜๋Š” DOM ๊ฐ์ฒด๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋Š”๋ฐ,
ref์˜ current๊ฐ€ ์กด์žฌํ•˜๋ฉด์„œ current๊ฐ€ ํ˜„์žฌ์˜ event.target์„ ํฌํ•จํ•˜๊ณ  ์žˆ์ง€ ์•Š์„ ๋•Œ = ์ฆ‰, current์™€ ์ด๋ฒคํŠธ ํƒ€๊ฒŸ์˜ DOM๊ฐ์ฒด๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ๋•Œ setState๋ฅผ false๋กœ ๋ฐ”๊พผ๋‹ค.

์•„๋ž˜๋Š” ํ—ค๋”์˜ ๋‹ค๋ฅธ ์˜์—ญ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ์˜ ์ฝ˜์†”์ด๋‹ค. ์ด๋ฒคํŠธ ํƒ€๊ฒŸ์—๋Š” ํ—ค๋”๊ฐ€, current์—๋Š” Input์ฐฝ์„ ๊ฐ์‹ผ div๊ฐ€ ๋‹ด๊ฒจ์žˆ๋‹ค.

์•„๋ฌดํŠผ ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊นฅ ์˜์—ญ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
์ง€๊ธˆ ์ฝ”๋“œ์˜ ํ•œ๊ณ„๊ฐ€ ์žˆ๋‹ค๋ฉด, ๋‹ค๋ฅธ ํ—ค๋” ์˜์—ญ์„ ๋ˆŒ๋ €์„ ๋•Œ๋งŒ ๊ฒ€์ƒ‰์ฐฝ์ด ๋‹ซํžŒ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ํ—ค๋”์˜์—ญ์„ ๋ฒ—์–ด๋‚˜๋ฉด ์•ˆ ๋˜๋Š” ์ .. ใ… ใ… 

 

ํ•œ๊ธ€, ์˜์–ด์— ๋”ฐ๋ฅธ ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰

 

๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ๋จผ์ € ๋“  ์ƒ๊ฐ์€, ๋งค๋ฒˆ ๊ฒ€์ƒ‰ํ•  ๋•Œ๋งˆ๋‹ค ํŒŒ์ด์–ด๋ฒ ์ด์Šค์—์„œ ์•„ํ‹ฐ์ŠคํŠธ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์œผ๋‹ˆ ๋ฆฌ๋•์Šค์— ์ƒํƒœ๋ฅผ ์ €์žฅํ•ด์„œ ๊ฐ€์ ธ๋‹ค ์จ์•ผ๊ฒ ๋‹ค!.. ์˜€๋‹ค. ๊ทธ๋ž˜์„œ ๋ฉ”์ธํŽ˜์ด์ง€์— ์ ‘์†ํ•  ๋•Œ ๋ฆฌ๋•์Šค์— ๋ฆฌ์ŠคํŠธ๋ฅผ ์ €์žฅํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

 

 

์ด์–ด์„œ ๊ฒ€์ƒ‰ ํ‚ค์›Œ๋“œ์˜ ๊ณต๋ฐฑ์„ ์ œ๊ฑฐํ•˜๊ณ , ์˜๋ฌธ์ผ ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ํ‚ค์›Œ๋“œ๋ฅผ ๋‹ค๋“ฌ์—ˆ๋‹ค.

// ๋‹จ์–ด ์†Œ๋ฌธ์ž + ๊ณต๋ฐฑ์ œ๊ฑฐํ•˜๋Š” ํ•จ์ˆ˜
export const trimmingKeyword = (keyword: string) =>
  keyword.toLowerCase().replace(/ /g, '');

 

ํ•œ๊ธ€์ผ ๊ฒฝ์šฐ์™€ ์•ŒํŒŒ๋ฒณ์ผ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ์„œ ๊ฒ€์ƒ‰ํ•ด์•ผ ํ•˜๋Š” ๋Œ€์ƒ์ด ๋‹ฌ๋ž๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๊ธ€์ผ ๊ฒฝ์šฐ๋ฅผ ์ฐพ์•„๋‚ด๋Š” ๊ฒƒ์ด ํ•„์š”ํ–ˆ๋‹ค!

export const krRegex = /[ใ„ฑ-ใ…Ž|ใ…-ใ…ฃ|๊ฐ€-ํžฃ]/;

 

๊ทธ๋ž˜์„œ ์ตœ์ข…์ ์œผ๋กœ ์™„์„ฑ๋œ ํ•จ์ˆ˜..

  // ๊ฒ€์ƒ‰๊ฒฐ๊ณผ submit ํ•จ์ˆ˜
  const submitKeyword = async (e: FormEvent<HTMLFormElement>) => {
    ...

    // ํ•œ๊ธ€์ผ ๊ฒฝ์šฐ nameKr์—์„œ, ์˜๋ฌธ์ผ ๊ฒฝ์šฐ name์—์„œ ์ผ์น˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ฐพ๊ธฐ
    if (krRegex.test(searchKeyword)) {
      searchResult =
        artists.find(
          (artist) =>
            trimmingKeyword(artist?.nameKr || '์—†์Œ') === searchKeyword,
        ) ?? null;
    } else {
      searchResult =
        artists.find(
          (artist) => trimmingKeyword(artist?.name || '์—†์Œ') === searchKeyword,
        ) ?? null;
    }

    ...

    setShowSearchInput(false);
  };

๊ฒ€์ƒ‰๊ฒฐ๊ณผ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ์—๋Š” params๋กœ ์•„ํ‹ฐ์ŠคํŠธ ์ •๋ณด ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์œ ํŠœ๋ธŒ ์˜์ƒ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ณ ,
์—†์„ ๊ฒฝ์šฐ์—๋Š” ์—๋Ÿฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.

 

 

 

์ด๋ฒˆ์—๋Š” ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ•˜๋ฉด์„œ ๊ฒ€์ƒ‰๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด๋ณด์•˜๋‹ค.
ํŠนํžˆ ์ปดํฌ๋„ŒํŠธ์˜ ์™ธ๋ถ€ ํด๋ฆญ์„ ๊ฐ์ง€ํ•˜๋Š” ๊ฒƒ์€ ๋‚˜์ค‘์— ๋ชจ๋‹ฌ์ฐฝ์„ ๊ตฌํ˜„ํ•  ๋•Œ๋„ ์š”๊ธดํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

728x90