선택 항목 삭제하기(전체 배열을 필터링 후 다시 저장하는 방법)

GOGO·2024년 11월 17일
0

홈 화면에서 다이얼로그를 클릭한 후 북마크 버튼을 클릭하면 북마크 페이지에서 해당 데이터를 조회하도록 localstorage를 활용한 로직을 구현했다.

북마크 페이지에서 선택모드를 통해 여러 항목을 선택하고 삭제할 수 있는 기능을 구현하는 과정을 기록하려고 한다

조회한 데이터

function index() {
	const [data, setData] = useState([]); // 로컬 스토리지에서 가져온 데이터를 저장
  
    const getData = () => {
      const getLocalStorage = JSON.parse(localStorage.getItem("bookmark"));

      // 데이터가 있거나 null이 아니면 조회하기
      if (getLocalStorage || getLocalStorage !== null) setData(getLocalStorage);
      else setData([]); // 기본이 빈 배열이지만 안정성을 위해서 작성
    };
  
    useEffect(() => {
      getData();
    }, []);
}
  • getLocalStorage 함수에서 getItem을 이용해서 로컬스토리지의 "bookmark"라는 키에 해당하는 값을 가져온다.
  • if문으로 로컬스토리지에서 가져온 값이 null이 아니거나 데이터가 있을 때 상태를 조회한다.
  • getLocalStorage가 null이면 빈 배열로 설정한다.
  • useEffect로 컴포넌트가 처음 마운트 될 때 데이터를 가져온다.

선택 항목 삭제

선택모드 활성화, 취소

index.tsx

function index() {
    const [selectMode, setSelectMode] = useState(false); // 선택 모드 상태
    const [selectedItems, setSelectedItems] = useState([]); // 선택된 카드 ID 저장

    const handleSelectMode = () => setSelectMode(true); // 선택하기
    const CancelSelectMode = () => {
      // 선택모드 취소
      setSelectMode(false);
      setSelectedItems([]); // 선택된 항목들을 해제
    };
}
  • 선택하기 버튼에 onClick 함수로 handleSelectMode, 취소 버튼에 onClick 함수로 CancelSelectMode을 넣어주었다.
  • 취소했을 때는 기존에 선택된 항목을 모두 해제하도록 setSelectedItems([]);를 추가했다.

Card 컴포넌트에서 항목 선택

index.tsx

function index() {
    const handleSelectItems = (id: string) => {
      setSelectedItems((prev) => {
        if (prev.includes(id)) {
          // 이미 항목 id가 있을 때
          return prev.filter((itemId) => itemId !== id); // 같을 때는 배열에서 제거하고 반환
        } else {
          return [...prev, id];
        }
      });
    };
  
  return(
    <main className={styles.page__contents}>
      {data.map((item: CardDTO) => {
        return (
          <Card
            prop={item}
            key={item.id}
            selectMode={selectMode}
            isSelected={selectedItems.includes(item.id)} // 선택 상태 여부를 확인(selectedItem에 해당 id를 포함하고 있는지)
            onSelect={() => {
              handleSelectItems(item.id);
            }}
            />
        );
      })}
    </main>
  )
}

Card.tsx

interface Props {
  prop: CardDTO;
  selectMode: boolean; // 선택모드
  isSelected: boolean; // 선택 여부 확인
  onSelect: () => void; // id를 매개변수로 받아 처리하고 있음
}

function Card({ prop, selectMode, isSelected, onSelect }: Props) {
  return (
    <div className={styles.card}>
      {selectMode && (
        <input
          type="checkbox"
          defaultChecked={isSelected}
          onChange={onSelect}
        />
      )}
      // 중략
	</div>
  )
}
  • selectMode를 전달해서 selectMode일 때 체크박스가 활성화 되도록 한다.
  • isSelected는 selectedItems.includes(item.id)를 통해서 각 항목의 선택 여부를 확인하고 체크/미체크를 표시한다.
  • handleSelectedItems에서 이미 항목이 선택되어 있는 경우 filter를 통해 그 항목을 배열에서 제거하고 반환한다. 선택되어있지 않은 경우에는 ...prev, id를 통해서 배열에 추가한다. (이미 선택된 아이템은 선택 해제, 아니라면 선택)
  • Card 컴포넌트로 props, selectMode, isSelected, onSelect를 넘겨준다.

선택 항목 삭제하기

index.tsx

// 선택한 항목 삭제 후 선택모드 종료
const deleteSelectedItems = () => {
  const updatedData = data.filter((item) => !selectedItems.includes(item.id)); // 선택된 항목을 제외한 항목만 남김
  setData(updatedData);
  localStorage.setItem("bookmark", JSON.stringify(updatedData));
  CancelSelectMode(); // 삭제 후 선택 모드 종료
};
  • updatedData로 선택된 항목을 제외한 항목만 남기고 setData로 데이터 상태를 updatedData로 업데이트 하면 화면에 렌더링 된 데이터에 반영된다.
  • setItem으로 삭제된 데이터를 로컬스토리지에 반영한다.
  • CancelSelectMode 함수로 선택 모드를 종료한다.
profile
#💻 #FE #💡 #📓

0개의 댓글