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
๋ก ์ํฐ์คํธ ์ ๋ณด ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์ ํ๋ธ ์์ ๋ฆฌ์คํธ๋ฅผ ๋ณด์ฌ์ฃผ๋ ํ์ด์ง๋ก ์ด๋ํ๊ณ ,
์์ ๊ฒฝ์ฐ์๋ ์๋ฌ ํ์ด์ง๋ก ์ด๋ํ๋๋ก ๊ตฌํํ๋ค.
์ด๋ฒ์๋ ๋ง์ ๊ณ ๋ฏผ์ ํ๋ฉด์ ๊ฒ์๊ธฐ๋ฅ์ ๊ตฌํํด๋ณด์๋ค.
ํนํ ์ปดํฌ๋ํธ์ ์ธ๋ถ ํด๋ฆญ์ ๊ฐ์งํ๋ ๊ฒ์ ๋์ค์ ๋ชจ๋ฌ์ฐฝ์ ๊ตฌํํ ๋๋ ์๊ธดํ๊ฒ ์ฌ์ฉํด ๋ณผ ์ ์์ ๊ฒ ๊ฐ๋ค.
'๐ Studying > ๐ TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Next.js] Next.js์ SSG, ISR (0) | 2023.02.01 |
---|---|
[Next.js] Next.js ๊ธฐ๋ณธ ๊ฐ๋ (0) | 2023.01.31 |
[TypeScript] redux-toolkit๊ณผ redux-thunk ๊ฐ์ด ์ฌ์ฉํ๊ธฐ (0) | 2023.01.26 |
[TypeScript] ๋ฆฌ์กํธ ํ์ด์ด๋ฒ ์ด์ค ์์ ๋ก๊ทธ์ธ ํธ์ํฐ ์ถ๊ฐํ๊ธฐ (1) | 2023.01.25 |
[TypeScript] ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๋ฐ๋ฅธ ํค๋ ๋ณ๊ฒฝ์ ๋ํ ๊ณ ์ฐฐ (0) | 2023.01.24 |
Comment