에러발생 & 해결방법

구현해야하는 기능은 메뉴를 눌렀을때, 하나의 메뉴텝만 클릭이 되어야하고,

알맞는 스타일 효과를 주는 기능을 만들어야했습니다.

기존에는 includes 메소드를 사용하여 배열에 특정 요소가 포함되어 있는지를 판별하였지만,

이 방식은 한글 메뉴나 띄어쓰기를 포함한 메뉴에서 활성화 효과가 제대로 적용되지 않는 문제가 있었습니다.

문제를 해결하기 위해, 상태 관리를 통해 현재 선택된 메뉴의 인덱스를 추적하는 방식으로 개선하였습니다.

리액트의 useState를 활용해 선택된 메뉴의 인덱스를 상태로 저장하고,

이 상태를 업데이트하는 함수를 onClick 이벤트 핸들러로 설정하였습니다.

사용자가 선택한 메뉴만 활성화 효과를 받도록 수정하였습니다.

 

기존의 코드

className={
 currentPathName.includes(firstChar.name) && 'active'
}

기존 코드에서는 className이 currentPathName.includes(firstChar.name)을 이용해 

'배열에 특정 요소가 포함되어 있는지' 판별하고 있었습니다.

그러나 이 방식을 사용하면 한글로 표시된 메뉴나 띄어쓰기를 포함하고 있는 메뉴에서는 'active' 효과가 적용되지 않는 문제가 발견되었습니다.

 

index값을 비교하여 하나의 메뉴 탭만 클릭되도록 교체하였습니다.

 

수정된 코드

 

우선, 부모 컴포넌트에 값을 저장할 state 상태를 하나 생성하였습니다.

const [countIndex, setCountIndex] = useState(0);

상태의 초기값을 0으로 지정한 이유는 index값이 0부터 시작하기 때문입니다. 

만약 id값이 1부터 시작한다면 초기값을 1로 변경해주면 됩니다.

const handleOnClick = (e, idx) => {
    setCountIndex(idx);
  };

 

그 다음 handleOnClick 함수를 생성하고, 이 함수에서는 map() 함수의 idx 값을 인자로 받아 

setCountIndex(idx)를 호출하여 idx 값을 countIndex 상태에 저장합니다.

{workspaceNames?.map((firstChar, idx) => (
  <OneOfWorkspaceBox key={firstChar.id}>
   <WorkspaceWrapper>
    <WorkspaceList
     className={countIndex === idx && 'active'}
     value={firstChar.name}
     onClick={e => handleOnClick(e, idx)}
     >
    {firstChar.first_char}
    </WorkspaceList>
   </WorkspaceWrapper>
  </OneOfWorkspaceBox>
))}

이 때, countIndex 상태와 각 요소의 idx 값이 같다면, 즉 선택된 메뉴의 인덱스와 각 요소의 인덱스가 같다면 

'active' 클래스를 적용합니다. 마지막으로, onClick 이벤트 핸들러로 handleOnClick 함수를 지정합니다.

복사했습니다!