React
[React] Custom Hook 만들기
sueeee-e
2025. 2. 5. 22:07
Custom Hook 이란?
반복되는 로직을 분리하여 재사용할 수 있게 만든 것
*2가지 조건*
- 이름이 use로 시작되어야 한다.
- react hook을 포함해야 한다. (useState, useEffect .. )
react의 특별한 기능이 아니라 훅 디자인을 따르는 관습이다. -공식문서-
*적절한 추상화레벨을 가져야 재사용하기 쉬우니 너무 구체적이거나 추상적인 로직은 지양하며 커스텀 훅을 사용해보자
[요구사항]
나는 관리자 페이지를 만들면서 목록을 만들 때가 많은데 이때 항상 필요한 기능이 체크박스이다.
상품이나 회원 목록 앞에 체크박스를 두어 가장 상단의 체크박스를 클릭했을 때는 전체선택이 되고, 개별선택, 다시 클릭했을 때는 선택된 항목 삭제 등의 기능이 있어야 하고 마지막으로 선택된 항목들은 따로 저장해두어야 한다.
이를 useCheckboxSelection.js 라는 이름으로 커스텀 훅을 만들었다.
[간단한 설명]
1. useState 의 기존 리액트 훅을 사용해서 [selectItems, setSelectItems]를 관리한다.
2. 전체선택 handleSelectAll, 개별선택 handleSelectItem, 선택삭제 handleDeleteSelected
import { useState } from 'react'
const useCheckboxSelection = (items, key) => {
const [selectedItems, setSelectedItems] = useState([])
// 전체 선택
const handleSelectAll = (event) => {
if (event.target.checked) {
setSelectedItems(items.map((item) => item[key])) // key를 동적으로 사용
} else {
setSelectedItems([])
}
}
// 개별 선택
const handleSelectItem = (itemKey) => {
setSelectedItems((prevSelected) =>
prevSelected.includes(itemKey)
? prevSelected.filter((key) => key !== itemKey)
: [...prevSelected, itemKey],
)
}
// 선택된 항목 삭제
const handleDeleteSelected = (setItems) => {
setItems((prevItems) => prevItems.filter((item) => !selectedItems.includes(item[key]))) // key를 동적으로 사용
setSelectedItems([])
}
return { selectedItems, handleSelectAll, handleSelectItem, handleDeleteSelected }
}
export default useCheckboxSelection
이렇게 만들어진 커스텀 훅을 다른 컴포넌트에서 어떻게 사용하는지까지 알아보자
const useCheckboxSelection = (items, key)
아이템과 키를 받아오는 것만 신경써주면 된다.
import useCheckboxSelection from '@/hooks/useCheckboxSelection'
import {useState} from 'react'
const [optionSets, setOptionSets] = useState([])
const optionSetsCheckbox = useCheckboxSelection(optionSets, 'id')
return(
//전체선택
<CFormCheck
checked={optionSetsCheckbox.selectedItems.length === optionSets.length}
onChange={optionSetsCheckbox.handleSelectAll}
/>
//개별선택
<CFormCheck
checked={optionSetsCheckbox.selectedItems.includes(set.id)}
onChange={() => optionSetsCheckbox.handleSelectItem(set.id)}
/>
)
결과!