React

개별 토글 리스트

minsun309 2024. 9. 11. 11:14

여러 리스트 중 리스트들이 개별로 기능하는 방법에 대해 정리했다.

 

고려할 사항

  • 리스트 중 클릭한 리스트만 열고 닫을 수 있어야 한다.
  • 다른 리스트를 열더라도 기존 열린 리스트에 영향이 없어야 한다.

리스트 click 이벤트를 주어 handleShowDetail 함수를 통해 해당 리스트의 값을(여기서는 index) 받아researchDetailLiStates에 저장된 값 중 빋아 온 리스트에 대한 값을 반전 시켜 새로운 상태를 업데이트한다.

const [researchDetailLiStates, setResearchDetailLiStates] = useState({});
const handleShowDetail = (index) => {
  // setResearchDetailLiStates 함수를 사용하여 이전 상태를 가져오고, 해당 인덱스의 값을 반전시킨다.
  setResearchDetailLiStates((prev) => ({
    ...prev, // 이전 상태를 복사합니다.
    [index]: !prev[index], // 해당 인덱스의 값을 반전시켜 새로운 상태를 업데이트한다.
  }));
};

 

클릭 이벤트를 통해 0번째 리스트 클릭 시 researchDetailLiStates 값은 {0: true, 1: false, 2: false} 로 변경된다. (0번에 대한 불리언 값을 반전시킨다.) {0: true, 1: false, 2: false} 이 상태를 활용해 client 화면에 true인 값만 화면에 보이게 한다.

{researchDetailLiStates[index] && (
  <div className="evidence_detailArea">
    {/* ... */}
  </div>
)}

 

 

전체 코드

"use client";
import { useState } from "react";

export default function Test() {
  const [detailLiStates, setDetailLiStates] = useState({});
  
  const handleShowDetail = (index) => {
    setDetailLiStates((prev) => ({
      ...prev,
      [index]: !prev[index],
    }));
  };

  return (
    <ul className="list w-[500px] mx-auto">
      {[1, 2, 3].map((list, index) => (
        <li key={index}>
          <div className="list_titleArea">
            <p className="list_link">제목 {index}</p>
            <p
              className={
                detailLiStates[index]
                  ? "list_detail_btn list_detail_btn_selected"
                  : "list_detail_btn"
              }
              onClick={() => handleShowDetail(index)}
            >
              세부정보 {index}
            </p>
          </div>
          {detailLiStates[index] && (
            <div className="list_detailArea">
              <div className="detail_conTxt">
                <p className="detail_title">상세내용</p>
              </div>
              <ul className="detail_conTable">
                <li>
                  <p>상세</p>
                  <p>상세1</p>
                </li>
              </ul>
            </div>
          )}
        </li>
      ))}
    </ul>
  );
}

 

 

결과