본문 바로가기

Web/NextJS

[Next JS 14 웹사이트 만들고 배포까지 A to Z] SSR 페이지에서 useState 사용하기

NextJS를 공부하다 보면 페이지에 function을 넣어야 하는 일이 자주 일어난다. 단순히 반복 작업을 줄이기 위해 사용하기도 하고 fetch한 데이터를 처리하기 위해서도 사용한다. 웹사이트를 개발하면서 나도 메인페이지에 useState 기능을 넣을 일이 있었다.

 

 

다음과 같이 학습자료 탭을 누를 경우 드롭메뉴가 펼쳐지는 기능을 구현하기 위해서는 useState를 이용해야만 했다.

 

Q1. css를 사용해서 구현하면 되는 것 아닌가?

 

물론 css에 hover라는 기능이 있어서 hover를 사용하면 되는 것 아닌가? 하는 의문이 들 수 있다. 하지만 내 경우는 hover를 사용하기엔 원하는 기능이 조금 달랐다.

 

 

코드를 확인하면 ul 태그 안에 li 요소들이 들어있는 것을 확인할 수 있다.  li 요소에 hover 기능을 넣을 경우 li 요소를 벗어나면 바로 드롭 메뉴가 닫히는 현상이 발생했다. 

 

반면 내가 원하는 기능은 드롭메뉴가 펼쳐질 경우 마우스가 드롭메뉴 밖을 벗어나는 경우에만 드롭메뉴가 닫히길 원했다.

 

Q2. 그렇다면 javascript를사용해서 구현하면 되겠다.

 

여기서 또 문제가 발생한다. 내가 원하는 기능을 구현하기 위해서는 useState를 사용해야 했는데 useState는 Client Component에서만 작동했기 때문에 SSR을 포기하거나 부분 컴포넌트화를 해야만 했다.

 

Q3. SSR 페이지에서는 useState 사용이 불가한가?

 

Next.js에서는 useState 훅이 Client Component에서만 돌아가게 하기 때문에 부모 요소가 Server Component일 경우 오류를 발생시켜 사용을 못하게 했다. 한마디로 해당 부분만 컴포넌트로 따로 분리해서 'use client' 선언을 해줘야만 했다.

 

P1. 드롭메뉴의 위치를 정확히 잡지 못해 몇일간 고생했다.

 

내가 원하는 것은 그림과 같이 ul 요소 밖에서 드롭 메뉴가 펼쳐지는 것이었다. 하지만 li 요소와 드롭메뉴를 묶어서 컴포넌트로 만드려고 하다 보니

다음과 같은 그림처럼 드롭메뉴가 펼쳐지게 되었고 디자인이 엉망이 되었다. 

 

해결방법

 

그림과 같이 li요소와 드롭메뉴를 분리한 후 드롭메뉴 컨테이너에 absolute값을 넣어줘서 부모요소에 영향받지 않게 하였다. 

그 후 다음과 같이 컴포넌트 요소를 정의해준 후 

메인 페이지 레이아웃에서 다음과 같이 사용하였다.

 

결론

 

SSR 페이지에서 useState, useEffect를 사용하고 싶은 경우에는 해당 부분만 컴포넌트로 따로 분리하여 'use client'선언을 해준 후 구현을 하면 된다.