IT/React.js

[React] 열고닫는 메뉴 , 메롱하는 메뉴, 다중 useState 관리

월공 2023. 12. 31. 05:08
728x90
300x250

위 와 같은 기능을 만든다고 칩시다.
원래 css 이쁘게 tailwind 로 잡혀있는데 포스팅 하느라 다 빼서 없어보이는 점 양해부탁드립니다.
말이 메롱이지 , 열고닫는 메뉴, 혹은 클릭 했을때 해당 현상을 유지하는 식은 웹 사이트에서 흔히 사용되는 기능인데
근데 이 간단한걸 리액트 스럽게 반영하려니 살짝 뇌 정지가 왔어서 (jQuery 만 사용하던 응빱이라..)
복습겸, 기록겸, 남겨둡니다.

물론 아래 처럼 열고 닫는 상태들을 관리 할 수도 있겠지만 가오가 있지 다중 상태 관리로 진행합니다.

const [부모1, set부모1] = useState(false);
const [부모2, set부모2] = useState(false);
const [부모3, set부모3] = useState(false);


다중 뭐시기는 아래 처럼 진행 할 수 있습니다.
const { 부모1, 부모2, 부모3 } = filterValues; 요런식으로 쓰는 뭐라했었는데 정식명칭이 뭔지 기억이 안나네요 ㅋ
분할 뭐시기였나 ..

const initialFilter = {
      부모1: false,
      부모2: false,
      부모3: false,
};


export default function App() {

    const [filterValues, setFilterValuses] = useState(initialFilter);
    const { 부모1, 부모2, 부모3 } = filterValues;
    
   	.... 생략

페이지에 부모1,부모2,부모3 에 쭈루룩 있고 상태는 전부 false 로 놨다가 클릭 하는것마다 true 로 바꿔서 메롱 하는걸 보여주고자 합니다.


 

...생략

const filterEvent = (event) => {
      const filter = event.currentTarget.dataset.filter;

      setFilterValuses((prevFilterValues) => ({
          ...prevFilterValues,
          [filter]: !prevFilterValues[filter]
      }));
  }

const FilterDetailList = ({filter}) => {
      return (
          <div>
                - 반갑다 내가 {filter} 자식이다.
          </div>
      );
  }

return (
    <>
      <div>
          <div>
              <div data-filter="부모1" onClick={filterEvent}>
                  <div>부모1</div>                  
              </div>
              {filterValues.부모1 && <FilterDetailList filter="부모1" />}
          </div>
          <div>
              <div data-filter="부모2" onClick={filterEvent}>
                  <div>부모2</div>                  
              </div>
              {filterValues.부모2 && <FilterDetailList filter="부모2" />}
          </div>
          <div>
              <div data-filter="부모3" onClick={filterEvent}>
                  <div>부모3</div>                  
              </div>
              {filterValues.부모3 && <FilterDetailList filter="부모3" />}
          </div>         
      </div>
    
    </>
  )

filterEvent 는 부모1,2,3 에 달린 이벤트이고 클릭 되는 순간 해당 event 의 currentTarget 에 data 로 설정되있는 filter 값을 가져다줍니다.
filterEvent 함수 호출할때 파라미터로 그냥 가져갔어도 됐는데 dataset 은 그냥 써봤어요

그리고 아래 set 에서 선택한 부모값대로 true 혹은 false 로 세팅을 해줍니다.
사실 열고닫는 기능은 아래가 핵심이라해도 과언이 아니겠네요

setFilterValuses((prevFilterValues) => ({
  ...prevFilterValues,
  [filter]: !prevFilterValues[filter]
}));


FilterDetailList 가 자식의 내용이기 때문에 클릭된 부모의 값이 true 라고 한다면 && 로 체크를해서 보여주고 말고를 정해줍니다.

실행을 해보면 아래처럼 열고닫는게 잘 될겁니다.

콘솔을 찍었을때도 열은 부모값만 true 로 잘 바뀌는것을 확인 할 수 있습니다.

 

아래는 전체 소스

import './App.css'
import { useState } from "react";

const initialFilter = {
      부모1: false,
      부모2: false,
      부모3: false,
};

export default function App() {

  const [filterValues, setFilterValuses] = useState(initialFilter);
  const { 부모1, 부모2, 부모3 } = filterValues;  

  const filterEvent = (event) => {
      const filter = event.currentTarget.dataset.filter;

      setFilterValuses((prevFilterValues) => ({
          ...prevFilterValues,
          [filter]: !prevFilterValues[filter]
      }));
  }

  const FilterDetailList = ({filter}) => {

      return (
          <div>
                - 반갑다 내가 {filter} 자식이다.
          </div>
      );
  }

  console.log(filterValues);
  
  return (
    <>
      <div>
          <div>
              <div data-filter="부모1" onClick={filterEvent}>
                  <div>부모1</div>                  
              </div>
              {filterValues.부모1 && <FilterDetailList filter="부모1" />}
          </div>
          <div>
              <div data-filter="부모2" onClick={filterEvent}>
                  <div>부모2</div>                  
              </div>
              {filterValues.부모2 && <FilterDetailList filter="부모2" />}
          </div>
          <div>
              <div data-filter="부모3" onClick={filterEvent}>
                  <div>부모3</div>                  
              </div>
              {filterValues.부모3 && <FilterDetailList filter="부모3" />}
          </div>         
      </div>
    
    </>
  )
}

별거 아닌 기능이더라도 직접 해보는게 중요한듯 합니다.
사실 jQuery 이용해서 하라하면 코웃음 치면서 금방 끝냈을거같은데 react로 막상 처리하려니 까다롭더군요
물론 큰 기능도 아니거니와, 더 좋은 소스도 많겠지만 저 같은 리액트 초보분들에게 조금이라도 도움이 되었으면 좋겠네요

원래는 타입스크립트로 했던거라 이상한 에러 엄청 떠서 이 부분도 상당히 짜증이 났네요ㅋ
위 filterEvent 함수에 파라미터 받을때에도, filter 타입선언할때도 엄청 에러떠서 아래와 같이 해결 했네요

const filterEvent = (event: React.MouseEvent<HTMLElement>) => {
    const filter = event.currentTarget.dataset.filter as keyof typeof filterValues;

 

728x90
300x250