๋ฆฌ์กํธ ๊ณต๋ถ๋ฅผ ์์ํ๊ณ ์คํฐ๋์๋ค๊ณผ ์คํ ์ดํ (https://smartstore.naver.com/freshmentor) ํด๋ก ์ฝ๋ฉ์ ์์ํ์ต๋๋ค. ํด๋น ํฌ์คํธ๋ ์คํฐ๋๋ฅผ ์งํํ๋ฉฐ ๋ฐ์ํ ๋ฌธ์ ์ ๊ณผ ํด๊ฒฐ๊ณผ์ ์ ๊ธฐ๋กํฉ๋๋ค !
์ผ๋จ 1์ฐจ์ ์ผ๋ก ์ด๋ฒ ํด๋ก ์ฝ๋ฉ์์ ์ ๊ฐ ๋งก์ ๋ถ๋ถ์ Header์ GNB์์ต๋๋ค. ์ด๋ ต์ง ์๊ฒ ์ฝ๋๋ฅผ ์งค ์ ์์ ๊ฑฐ๋ผ๊ณ ์๊ฐํ์ง๋ง ์ด์ ๋ง ๋ฆฌ์กํธ ๊ณต๋ถ๋ฅผ ์์ํ ์ ์๊ฒ๋ ์์์ธ๋ก ์ด๋ ค์์ด ๋ง์๋๋ฐ์ .. ๐ฅฒ
์ฒซ๋ฒ์งธ ๋ฌธ์ ๋ GNB์์ ๋ฐ์ํ์ต๋๋ค. GNB์ one depth๋ ๋งต์ ๋๋ ค ์์ํ๊ฒ ๋ง๋ค์์ง๋ง two depth๋ ์ถ์ฐ๋ฌผ, ์ํ๋ช ์ธ ์นดํ ๊ณ ๋ฆฌ์ ๊ฐ์ด ํ์ ์นดํ ๊ณ ๋ฆฌ๊ฐ ์๋ ํญ๋ชฉ์ด ์์์ด์.
GNB๋ฅผ ํ์ธํ๊ธฐ ์ ์๋ 'one depth๋ฅผ map์ผ๋ก ๋๋ฆฌ๊ณ tow depth๋ map์ผ๋ก ๋๋ ค ๋ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ํฉ์น๋ฉด ๋๊ฒ ๋ค!' ์๊ฐํ์๋๋ฐ์ ํ์์นดํ ๊ณ ๋ฆฌ๊ฐ ์๋ ํญ๋ชฉ์ ๋ณ์๋ฅผ ์ด๋ป๊ฒ ์ง์ผํ์ง ..? ์ด๋ ต๋๋ผ๊ณ ์ ใ ใ
const LINKS = [
{ mainLink: '๋ฒ ์คํธ', subLink: null },
{
mainLink: '๋์ฐ๋ฌผ',
subLink: ['๊ณผ์ผ', '์ฑ์', '๊ณก๋ฌผ'],
},
{ mainLink: '์์ฐ๋ฌผ', subLink: ['์ ์ฒ ', '๊ฑด์ด๋ฌผ'] },
{ mainLink: '์ถ์ฐ๋ฌผ', subLink: null },
{
mainLink: '๊ฐ๊ณต์ํ',
subLink: ['์ผ๋ฐ', '๋ฐ์ฐฌ', '์ฐจ๋ฅ', '๋ฒ๊ฟ', '๊ฐํธ๊ฐ์'],
},
{ mainLink: '์ ์ฒด์ํ', subLink: null },
];
๊ทธ๋ฐ๋ฐ ์์์ธ๋ก ๊ฐ๋จํ๊ฒ null๊ฐ์ ๋ฐํํ๋ฉด ๋๋ ๊ฑฐ ์์ด์. ์ด๋ ๊ฒ LINKS ๋ณ์๋ฅผ ์ง๊ณ
props.category.subCategory?.map((categoryItem, i)=>{
return <Link key={i}>{categoryItem}</Link>
})
์ต์ ๋ ์ฒด์ด๋์ผ๋ก map์ ๋๋ฆฌ๋ฉด null์ผ ๋๋ ๋ถํ์ํ ํ์ ์์๋ฅผ ๋ง๋ค์ง ์๊ธฐ ๋๋ฌธ์ two depth๋ฅผ ๋ฌด์ฌํ ์งค ์ ์์์ต๋๋ค. ์ฌ์ค ์ด๋ฒ์ GNB๋ฅผ ๋ง๋ค๋ฉฐ ์ต์ ๋ ์ฒด์ด๋ ๊ฐ๋ ์ ์ฒ์ ์๊ฒ๋์๋๋ฐ์
์ฐธ์กฐ๊ฐย nullish (null ๋๋ undefined)์ผ ๊ฒฝ์ฐ, ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๋์ ํํ์์ ๋ฆฌํด ๊ฐ์ undefined๋ฅผ ๋ฐํํ๋ ๋ฌธ๋ฒ์ ๋๋ค.
โ?.โ๋ก ๊ฐ๋จํ๊ฒ ์์ฑํ ์ ์๋ ์ต์ ๋ ์ฒด์ด๋ ๋๋ถ์ null ๊ฐ์ด ์๋ ๊ฐ์ฒด๋ฅผ ๋ฌธ์ ์์ด map์ผ๋ก ๋๋ ค ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์์ต๋๋ค.
๋ ๋ฒ์งธ๋ก๋ ์ด๋ ค์์ ๊ฒช์ ๋ถ๋ถ์ two depth์ ์ ์ฒด ์นดํ ๊ณ ๋ฆฌ๊ฐ ํธ๋ฒํ ๊ฒฝ์ฐ ํ ๋ฒ์ ๋จ๋ ๊ฒ์ด ์๋๋ผ
์ด๋ ๊ฒ ๊ฐ๋ณ์ ์ผ๋ก ๋จ๊ฒ ๋ง๋ค์ด์ผ ํ๋ค๋ ๊ฒ์ด์์ต๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ์๋ค๋ฉด querySelector, getElementById ๋ฑ์ ์จ์ ์ง์ ๋์์๋ฅผ ์ ํํด ์ฝ๋๋ฅผ ์ง ๋ฌด์ง ์ฌ์ ์ํ ๋ฐ์ .. ๋ฆฌ์กํธ๋ virtual DOM์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ทธ๋ด ์ ์์ด ๋ต๋ตํ ๋ถ๋ถ์ด ๋ง์์ต๋๋ค.
๋ฐ๋ก document.querySelector์ ๊ฐ์ css ์ ํ์๋ก ์์๋ฅผ ๋ถ๋ฌ์ฌ ๊ฒฝ์ฐ, ์ค์ DOM์ ์์๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ ์ญ ์ ๋ ํฐ๋ ์ฝ๋๋ฅผ ์ด ์ปดํฌ๋ํธ๊ฐ ์๋ ์ ์ฒด document๋ฅผ ๋์์ผ๋ก ํฉ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ ๊ฐ ์ํ๋ ํน์ DOM ์ด ์๋ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ์๋ DOM ์ ์ ๊ทผํ ์ง๋ ๋ชจ๋ฅธ๋ค๋ ๊ฒ ..
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ state๋ฅผ ์ฌ์ฉํด ๋ด๋ถ ์์๋ฅผ ์ ์ดํด์ผํ๋๋ฐ์ .. ์ ๋ ์ด state์ ๊ฐ๋ ์ด ์๋ฟ์ง๊ฐ ์์ ์ฝ๋๋ฅผ ์ง๋ ๊ฒ์ด ์ด๋ ค์ ์ต๋๋ค.
const [isHovering, setIsHovering] = useState(false);
const [targetGnb, setTargetGnb] = useState('');
๋จผ์ GNB๋ฅผ ์ ์ดํ๊ธฐ ์ํด์ useState ํ ์ ์ฌ์ฉํด ๋ง์ฐ์ค๋ฅผ ํธ๋ฒํ์ ๋์ ์ํ๊ฐ์ ๋ฐ๊พธ๊ธฐ ์ํ isHovering, ํ์ผ์ด ๋ GNB ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ฐพ๊ธฐ ์ํ targetGnb ๋ณ์ ๋ ๊ฐ๋ฅผ ์ค์ ํ์ต๋๋ค.
const handleMouseOver = (e) => {
setIsHovering(true);
if(e.target.nodeName === 'A'){
setTargetGnb(e.target.dataset.categoryItem)
}
console.log(targetGnb)
};
handleMouseOver ํจ์๋ GNB์ onMouseOver๊ฐ ๋ฐ์ํ์ ๋ ์๋ํ๋ ํจ์๋ก ๋จผ์ IsHovering์ ์ํ๋ฅผ true๋ก ๋ง๋ค๊ณ targetGnb๋ฅผ ์ ํ๋ ์์์ data-category-item์ผ๋ก ๋ถ๋ฌ์ต๋๋ค. ํธ๋ฒ ๋์ ๋ ํด๋น node์ ์ด๋ฆ์ด A๋ผ๋ฉด targetGnb๋ฅผ dataset.catetoryItem์ผ๋ก ๋ฐ์์ targetGnb๋ฅผ ์ ๋ฐ์ดํธ๋ฅผ ํฉ๋๋ค.
targetGnb๊ฐ ์์๋๋ก ์ ์ ๋ฐ์ดํธ ๋๊ณ ์๋์ง ์ฝ์์ ์ค๊ฐ์ค๊ฐ ์ฐ์ด๋ณด๋ฉฐ ํ์ธํด๋ด ๋๋ค !
์ด๋ผ๋ผ ๊ทธ๋ฐ๋ฐ ๋ง์ด์ฃ ..
์ฝ์์๋ targetGnb์ ์ด์ ๊ฐ์ด ์ถ๋ ฅ๋๊ณ ์ ๋ฐ์ดํธ ๋์ง ์๋ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค ^^
๋ฌธ์ ๊ฐ ๋ฌด์์ธ๊ฐ ๋ณด์ํ๋ .. console.log(targetGnb)์ ์์น๊ฐ ์๋ชป๋์๋๋ผ๊ณ ์.
useState๋ state ๊ฐ์ ๋ณํ๋ฅผ ๊ฐ์งํ๊ณ , ๋ฆฌ์กํธ๋ state๊ฐ ๋ณํํ์์ ๋ ํด๋น ์ปดํฌ๋ํธ๋ฅผ ๋ฆฌ๋๋๋ง ํฉ๋๋ค.
๋ฐ๋ผ์ handleMouseOver ํจ์ ๋ด์์ ์ฝ์์ targetGnb ๊ฐ์ ์ฐ๊ฒ ๋ ๊ฒฝ์ฐ, ์ ์ฒด ์ปดํฌ๋ํธ๊ฐ ๋ค์ ํธ์ถ๋๊ธฐ ์ ์ด๊ธฐ ๋๋ฌธ์ ์ ๋ฐ์ดํธ๊ฐ ๋์ง ์์ ๊ฐ์ ๋ฐํํ๋ ๊ฒ์ด์์ต๋๋ค. ๋ณ๊ฒฝ๋ targetGnb ๊ฐ์ ํ์ธํ๊ณ ์ถ๋ค๋ฉด handleMouseOver ํจ์ ๋ฐ์์ console.log(targetGnb)์ ์์ฑํ๋ฉด ๋ฉ๋๋ค.
์์ ํ๊ณ ์ฝ์์ ํ์ธํด๋ณด๋ targetGnb๊ฐ ๋ค์ด์ค๊ณ ์๊ตฐ์ ๐
{
props.category.mainCategory === props.targetGnb ?
props.category.subCategory && props.category.subCategory.map((categoryItem, i)=>{
return <Link key={i}>{categoryItem}</Link>
}) : ''
}
์ด์ targetGnb์ GNB์์ ์ ํํ ์นดํ ๊ณ ๋ฆฌ๊ฐ ๊ฐ์ ๊ฒฝ์ฐ์ two depth ํญ๋ชฉ์ผ๋ก map์ ๋๋ฆฝ๋๋ค.
์ด๋ ๊ฒ two depth๋ฅผ ๋งต์ผ๋ก ๋๋ฆฌ๋ฉด
์ง์ ! ์ด๋ ๊ฒ targetGnb์ ํด๋นํ๋ two depth ๋ฆฌ์คํธ๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ํ์ง๋ง ul ๋ฐ์ค๊ฐ ํด๋น๋๋ targetGnb ์ผ ๋๋ง ๋จ๋ ๊ฒ ์๋๋ผ ๋ชจ๋ ul์ด ํ ๋ฒ์ ๋จ๊ณ ์๋ค์ .. ^^
{props.links.subLink && props.links.mainLink === props.targetGnb ? (<ul className={style.twoDep} data-main={props.targetGnb}>
{
props.links.mainLink === props.targetGnb ?
props.links.subLink && props.links.subLink.map((link, i)=>{
return <li key={i} className={selected === i ? style.selectedList : style.list} onMouseOver={()=>{handleMouseOver(i); console.log(selected)}}><Link className={style.link} to={`/category/${link}`} key={i}>{link}</Link></li>
}) : ''
}
</ul>) : ''}
์ด ๋ฌธ์ ๋ li์ map์ ๋๋ฆฌ๋ ์กฐ๊ฑด์ ul์๋ ๋๊ฐ์ด ์ค์ ํด์คฌ๋๋ ๊ธ์ ํด๊ฒฐ๋์์ต๋๋ค !
one depth์ ๋ฌด์ฌํ ๊ตฌํ์ด ๋์์ง๋ง two depth ์นดํ
๊ณ ๋ฆฌ๋ฅผ ํด๋ฆญํ๋ ค๊ณ ํ๋ฉด li๋ค์ด ๋ชจ๋ ์ฌ๋ผ์ ธ๋ฒ๋ฆฌ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค .. ์ด์ ๊ฐ ๋ฌด์์ผ๊น ์ฝ๋๋ฅผ ๋ณด๋
const handleMouseOver = (e) => {
setIsHovering(true);
if(e.target.nodeName === 'A'){
setTargetGnb(e.target.dataset.categoryItem)
}
};
targetGnb๊ฐ ๋ ธ๋๋ค์์ด A์ผ ๋๋ง ์ ๋ฐ์ดํธ๊ฐ ๋์ด ํด๋น๋ ์์ญ์ ๋ฒ์ด๋๋ฉด targetGnb๊ฐ์ด ์ฌ๋ผ์ง๊ณ ์์์ต๋๋ค.
const handleMouseOver = (e) => {
if(!e.target.dataset.link) return
setTargetGnb(event.target.dataset.link)
};
๋ฐ๋ผ์ e.target.dataset.link ๊ฐ์ด ์์ ๋๋ ํจ์๋ฅผ ์ข ๋ฃํ์ฌ ํด๋น ์นดํ ๊ณ ๋ฆฌ๊ฐ ์ด์ ์ targetGnb๊ฐ์ ๊ณ์ ๊ฐ์ง๊ณ ์๋๋ก ์์ ํ๊ณ , setTargetGnb์ ์์ญ์ ์ถ์ํ๋ if๋ฌธ์ ์ง์ฐ๋ ๊ฐ๋จํ๊ฒ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค.
๋ค์ ๋ฌธ์ ๋ tow depth ๊ฐ๊ฐ์ ํด๋ฆญํ์ ๋ ๋ฐฐ๊ฒฝ์๊ณผ ๊ธ์จ์์ ๋ฐ๊พธ๋ handleMouseOver ํจ์๋ฅผ ํธ์ถํ ๋ ๋ฐ์ํ์ต๋๋ค.
one depth์์ onMouseOver ์ด๋ฒคํธ๋ฅผ ์คํํ๋ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก handleMouseOver(i) ํจ์๋ฅผ ํธ์ถํ์
Unhandled Thrown Error!
Too many re-renders. React limits the number of renders to prevent an infinite loop.
์์ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ด์ฉ์ ๋ณด๋ ๋๋ฌด ๋ง์ ๋ฆฌ๋ ๋๊ฐ ์ผ์ด๋๊ณ ์๋ ์ํฉ์ด์๋๋ฐ์..
<li onMouseOver={handleMouseOver}>
{link}
</li>
one depth ์์๋ ์ด๋ ๊ฒ handleMouseOver ํจ์ ์์ฒด๋ฅผ ์ ๋ฌํด๋ ๋ฌธ์ ๊ฐ ์์๋๋ฐ ์ two depth์์๋ ๋ฌธ์ ๊ฐ ์๊ธด๊ฑธ๊น์ ?
<li onMouseOver={handleMouseOver(i)}>
{link}
</li>
๋ฐ๋ก two depth์ ๊ฒฝ์ฐ, i๋ผ๋ ์ธ์๋ฅผ ๋๊ฒจ์ฃผ๊ณ ์๊ธฐ ๋๋ฌธ์ด์์ต๋๋ค. ์์ ๊ฐ์ด ์์ฑํ๋ฉด ํจ์ ์์ฒด๊ฐ ์ ๋ฌ๋๋ ๊ฒ์ด ์๋๋ผ ํจ์๋ฅผ ํธ์ถํ๋ ํํ๊ฐ ๋์ด๋ฒ๋ฆฝ๋๋ค. ๋ฐ๋ผ์ onMouseOver์ ๊ด๊ณ์์ด ๋ฐ๋ก ์คํ๋ฉ๋๋ค.
<li onMouseOver={()=>{handleMouseOver(i)}>
{link}
</li>
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ํจ์์ ์ธ์๋ฅผ ์ ๋ฌํด์ผํ ๊ฒฝ์ฐ, ํ์ดํ ํจ์๋ฅผ ์ด์ฉํด ํด๋น ํจ์์ ํธ์ถ๋ถ์์ ์ธ์๋ฅผ ๋๊ฒจ์ฃผ๋ฉด ๋ฉ๋๋ค.