[React] - FE 신입 포트폴리오 (준비 과정 기록용) | 스토리편

ain·2022년 8월 28일
0

포트폴리오

목록 보기
1/4
post-thumbnail

포트폴리오의 메인 페이지는 거의 다 완성하였고, 나의 대한 소개와 스토리를 더 볼 수 있는 스토리 부분을 어떻게 만들까 구상하고 있다.

현재 구상하고 있는 것은 총 세가지이다.

1. 첫 번째

메뉴 바에 있는 '스토리'를 클릭하면 나를 소개하는 내용의 목차들이 나열되어 있는 페이지로 이동한다.
목차 예) 개발을 시작한 이유, 나의 장단점 등.

2. 두 번째

메뉴 바에 있는 '스토리' 버튼 아래에 목차를 나열하고,

'스토리'를 클릭하면 목차 페이지로 이동하고,

'목차'를 클릭하면 해당 목차에 대한 내용이 나오는 페이지로 이동한다.

3. 세 번째

메뉴 바에 있는 '스토리' 버튼 아래에 목차를 나열하고 '스토리'를 클릭하면 메뉴바에 목차가 아코디언처럼 토글 되고,

'목차'를 클릭하면 목차들이 나열되어있는 페이지로 이동하며, 클릭했던 목차의 내용이 이동한 페이지에서 아코디언으로 열려있는 채로 페이지가 나타나게 한다.



+2022.09.04 업데이트

최종 구현

스토리 부분은 최종적으로 아코디언으로 구현해보았다. 링크가 너무 많이 걸려있으면 복잡해지고 보는 사람도 헷갈릴 것 같아서 메뉴바에 '스토리'로 넘어오면 '스토리' 페이지로 이동하고 여기서 모든 스토리를 볼 수 있도록 만들어보았다.
스토리 최종 화면

아코디언은 쉬울 줄 알았는데 예상외로 더 머리를 쥐어짰다. useState로 true false만 바꾸면 되는줄 알았더니 하나를 클릭하면 모든 아코디언이 열리고, useReducer로 하나하나 열리게 구현하는 걸 완성해놓았더니 아코디언 한개가 열려있을 때 다른 아코디언을 클릭하면 열려있던 아코디언이 닫히기만 하고 한번 더 클릭해야 클릭한 아코디언 열리는 상황이 발생했다.
그리고 또 어찌저찌 해서 위의 이슈는 해결했지만 열려있는 아코디언을 닫기위해 한번 더 클릭하면 닫히지가 않는 이슈가 또 발생한 것이다.(ㅠㅠ)

왜 이런 이슈가 발생한건지...

useState로 상태를 관리할 때에는 true와 false로만 관리해서 클릭한 아코디언 하나에만 true가 적용되는게 아니라 하나만 클릭해도 상태가 true가 되니까 모두 열리는 상황이 발생하는 것이다.
useReducer를 사용했을 때는 아코디언마다 id를 주고, 그 아이디와 state의 id가 동일 할 시(data.id === state.id), 그리고 open state가 false인 상태일 때 해당 id의 컨테이너 아코디언이 열릴 수 있게 만들어 봤다.
이렇게 하면 id가 같을때만 열리도록 조건을 걸어놔서 아코디언이 하나하나씩만 열리지만 boolean을 담당하는 open state가 true(아코디언이 하나라도 열려있을 때)일 때, 또 다른 아코디언을 클릭하면 false가 되기 때문에 클릭한 아코디언이 열리지는 않고 열려있던 아코디언이 닫히기만 하는 것이었다.

해결

구글의 힘을 빌려 react로 아코디언 구현하는 방법으로 찾아보니 useState로만 해결할 수 있는 방법이 있어 채택하기로 했다.

먼저, useState로 상태값을 문자열 '0'으로 초기화해준다.

const [state, setState] = useState('0');

아코디언의 요소를 map으로 반복해줄 때 map에서 가져온 index와 상태값이 같으면 상태값을 문자열 '0'으로 다시 초기화하고, 같지 않으면 index로 바꾼다. 상태값과 index가 같다면 true를, 같지 않다면 false를 active라는 변수로 아코디언 컴포넌트에 전달해준다.

초기 문자열 '0'인 상태에서 index가 0인 아코디언을 클릭하면 state는 0이 되고, 그 상태에서 index가 1인 아코디언을 클릭하면 state가 1로 바뀐다. state와 index가 같기때문에 active는 true가 되고 아코디언이 열리는 것이다.
열린 아코디언을 닫을 때를 보자. state가 1일 때 index가 1인 아코디언을 클릭하면 state === index 조건이 성립되어서 state가 문자열 '0'이 된다. 그렇게 되면 active가 false가 되기 때문에 아코디언이 닫히게 된다.

const handleToggle = (index) => {
  if (state === index) {
    return setState('0');
  }
  setState(index);
};

초기 상태값이 문자열 '0'인 이유는 숫자 0이 되면 index가 0인 요소를 눌렀을때 계속 toggle === idx 조건이 참이 되버려서 닫히지가 않는다. 초기화는 '0'이 아니여도 빈 문자열로 넣어도 된다.(idx와 값이 같지 않기만 하면 됨)

active가 true일 때에는 스토리 내용부분의 height을 auto로 설정되면 글자의 수대로 height이 늘어나고, false일때는 height이 null로 들어가서 숨겨진다.



참고

profile
프론트엔드 개발 연습장 ✏️ 📗

0개의 댓글