DrawMap: SelectBox 구현하기, 자식에서 부모로 값 전달하기/말줄임표 적용

지난편에 이어 selectBox 구현 글을 작성하겠다.
이번편이 굉장히.. 날 고통스럽게 만들었던 부분이다.

해당 편에서 구현해야 할 기능

  • 선택한 값을 select(.sbtn-select)에 띄우기
  • ButtonSelect 컴포넌트를 사용하는 페이지(CourseList)에 선택한 값들이 추가 박스(.cl-location)로 나타나게 하기

미리 보는 완성된 영상

select 완성

.sbtn-select에 선택한 값 띄우기


선택한 값이 들어갈 span 태그 .sbtn-select를 만들어주고, useState로 selectValue를 만든다.
저번편에 li태그 값들을 뿌려줬던 해당 코드에서 li태그 부분에 onClick 이벤트를 추가한다.
onClick 이벤트에 setSelectValue(`${it.item}`)를 넣어준다. 해당 코드는 li태그를 클릭하면 selectValue를 it.item값으로 변경해준다는 의미이다.
자, 그러면 원하는 li태그를 클릭했다면 해당 li 태그의 값이 selectValue에 들어가게 된다. 그러면 .sbtn-select에 selectValue 값을 넣어주면, 우리가 선택한 값이 띄워지게 되는 것이다.
여기서 추가로, html의 select 태그의 경우에는 값을 선택하기 전에 기본적으로 띄워주는 값을 설정할 수 있다. 그래서, 나도 해당 기능을 추가해주기로 했다.
ButtonSelect에 title이라는 props를 추가하여 부모 요소(CourseList)에서 title의 값을 받아준다. 해당 title이 값을 선택하기 전에 기본적으로 띄워줄 값이다.
.sbtn-select에서 삼항연산자를 통해 selectValue의 값이 있다면 selectValue를 뿌려주고, 값이 없다면(즉, 빈배열이라면) title값을 뿌리도록 해줬다.

스크린샷 2023-10-15 12 15 15 스크린샷 2023-10-15 12 14 55

.sbtn-select에 말줄임 표시


.sbtn-select에 들어오는 값이 너무 길면 말줄임 표시를 해주도록 했다.

white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

white-space:nowrap을 통하여 자동으로 줄바꿈하는 것을 막아준다.
그리고 overflow:hidden을 통해 지정한 박스 사이즈를 넘어가게 되면 잘라준다.
text-overflow:ellipsis를 통해 넘어간 부분을 말줄임표(…) 처리가 되도록 한다.

자식에서 부모로 값 전달하기


우리가 props를 사용할때 대부분 부모에서 자식요소로 값을 전달해준다. 그러나 나는 자식에서 부모로 값을 전달해야 하는 경우가 발생했다.

여기서 부모는 CourseList, 자식은 ButtonSelect이다.
CourseList는 page인데, 위의 완성 영상을 보면 값을 선택하면 select 박스 옆에 선택한 값의 박스(.cl-location)가 나타나야한다.
우리는 선택한 값을 자식에서만 다루는데, 이 자식에서 선택한 값을 부모로 보내서 해당 페이지(CourseList)에 작은 박스로 뿌려주도록 해야한다.

여튼, 결론은 자식에서 부모로 값을 전달해야 한다는 것

일단, 부모에 getTextValue(text)라는 함수를 만들어 준다. 그리고 자식에 props를 getTextValue를 만들어서 전달하는 값으로 getTextValue를 넘겨준다. 자식에게 해당 함수가 부모에 존재한다고 알려주는 것이다.

그리고 자식에서 해당 함수를 실행시켜 준다. 이때, 우리는 참고한 글과 는 조금 다르게 실행시킨다. useEffect를 사용해주는 것이다.

참고한 글 처럼 sendTextValue 함수(부모로 값 전달하는 함수)를 만들어서 실행시켜줘도 된다. 해당 방법으로 코드를 작성하면 li 태그의 onClick 이벤트가 실행되면서 sendTextValue 함수가 실행된다. 그러나 이 방법은 선택한 값이 select의 .sbtn-select는 바로 적용되지만 .cl-location에는 한 박자 늦게 적용된다.
내가 가장 처음 1을 선택하면 .cl-location은 나타나지 않는다. 그 다음에 2를 선택해야 .cl-location에 1 값이 나타나게 된다.

이런 기능적인 오류가 발생하는 이유를 추측하기로는 onClick에 두개의 함수(getTextValue랑 setSelectValue)가 있는데, selectValue 값이 getTextValue랑 동시에 실행돼서 selectValue값이 업데이트 되기 전에 getTextValue가 실행하는 것이 아닐까.. 따라서 값의 변경의 한 박자 느리게 반영된것이 아닐까 추측중이다.

따라서, 해당 기능 오류를 해결하기 위해서 useEffect를 사용해줘야 한다. useEffect로 변화를 바로 감지할 수 있도록 하는 것이다.
useEffect의 deps로 selectValue를 하여 selectValue의 값의 변경을 감지하면 getTextValue함수가 실행되도록 한다.

자식에서 getTextValue(selectValue)를 실행시키도록 해주면, 부모에서 getTextValue 함수가 실행되면서 setTextValue(text)를 (자식에서의 selectValue가 부모의 text에 들어오는 것) 통해 textValue에 값에 text(selectValue)가 들어가게 된다.
해당 코드를 적용하면 textValue가 .cl-location에 바로 적용된다!

위에 설명한 코드 로직은 다음과 같다.

  • 자식에서 값 선택(setSelectValue 실행)
  • selectValue의 변화를 useEffect가 감지
  • 부모로 값 전달 (getTextValue 실행)
  • 부모에서 getTextValue 실행 (setTextValue 실행)
  • .cl-location에 textValue 반영

ButtonSelect(자식) 코드는 위에 이미지 참고
CourseList(부모) 코드
주석은 치열한 오류잡기의 흔적..이므로 무시할 것 스크린샷 2023-10-15 12 15 57 스크린샷 2023-10-15 12 16 13

마치며


select 태그 기능을 직접 구현해봤는데, 처음에 생각한 것 보다는 엄청 어렵지는 않았다. 1편의 부분은 구현하는데 힘들기는 했어도 못할 정도는 아니었는데, 2편의 부분이.. 특히 getTextValue 부분이 정말.. 기능 오류..잡는게 너무 힘들고 어려웠다.. 포기할까 생각도 했지만, 그건 찝찝하고… 그리고 이렇게 오래 붙들고 있었는데 그 시간들이 아까웠달까
그래도 결론적으로는 잘 구현해서 정말 뿌듯했다. 완성한 결과물을 보니.. 그간 고생하고 힘들었던게 싹 사라진달까..
한달 후에 적고 있는 지금도 그때 생각하니 정말 감격스러운 감정이 든다..

해당 기능을 구현하면서 useEffect가 이런 거구나!!를 완벽히 깨달았고, useState 또한 완벽히 이해할 수 있었다.
그전에 강의를 보면서 할때는 useEffect랑 useState는 이런거구나..를 머리로만 이해했는데, 해당 기능을 구현하기 위해 별 자료를 다 찾아보고 내 프로젝트에 맞게 변경하려다보니 해당 기능들을 완벽히 이해할 수 있었다.
이래서.. 개발은 직접 원하는 프로젝트를 진행하면서 공부하라는 말이 이런거구나! 를 깨달았다.
이제 다음번에 select 태그 구현한다면 좀 더 빨리 잘 할 수 있을 것 같다.

참고 부모에서 자식, 자식에서 부모 값 전달하는 방법 prose, function
부모에서 자식, 자식에서 부모 값 전달하는 방법
useEffect 변화의 감지
css에서 텍스트 ellipsis(‘…‘)말줄임 표시 처리하는 방법
알아두면 유용한 잡다한 CSS

Comments