-
[React] Custom Hook을 사용하자Web/Front-End 2021. 5. 20. 11:57
Custom Hook은 아주 편한 기능 중 하나이다.
내가 사용하고싶은 컴포넌트나 로직을 미리 정의해두고 매개변수를 통해 자유롭게 어디서든 가져다 쓸 수 있으면서 Hook 내부에는 react문법이나 다른 hook을 포함 시킬 수 있어 함수형 컴포넌트 개발을 하면 빼먹을수가 없는 부분이다.
간단하게 내가 만든 예제를 통해 뭐가 간편한지 작성하도록 하겠다.
const usePage = () => { const [totalSize, setTotalSize] = useState(0) const [size, setSize] = useState(10) const [pageNumber, setPageNumber] = useState([]) const [selectedPage, setSelectedPage] = useState(1) const [maxPage, setMaxPage] = useState(10) const [pageBundle, setPageBundle] = useState(1) const [currentBundle, setCurrentBundle] = useState(1) useEffect(() => { return () => { setTotalSize(0) setSize(10) setPageNumber([]) setSelectedPage(1) setMaxPage(10) setPageBundle(1) setCurrentBundle(1) } }, []) useEffect(() => { setPageNumber([]) const perValue = totalSize / size const decimal = Math.floor(perValue) if (perValue > decimal) { calcPageNumber(decimal + 1) } else calcPageNumber(decimal) }, [totalSize]) useEffect(() => { if (pageNumber.length > maxPage) { const perValue = pageNumber.length / maxPage const decimal = Math.floor(perValue) if (perValue > decimal) { setPageBundle(decimal + 1) } else setPageBundle(decimal) } }, [pageNumber.length]) useEffect(() => { const bundlePer = selectedPage / maxPage const bundleDecimal = Math.floor(bundlePer) if (bundlePer > bundleDecimal) { setCurrentBundle(bundleDecimal + 1) } else setCurrentBundle(bundleDecimal) }, [selectedPage]) const calcPageNumber = (number) => { for (let i = 1; i <= number; i++) { setPageNumber(pageNumber => pageNumber.concat(i)) } } const pagingComponent = (bundle) => pageNumber.map((numberItem) => { if (maxPage * bundle >= numberItem && bundle <= pageBundle && numberItem > (bundle - 1) * maxPage) { return ( <li className={selectedPage === numberItem ? 'on paging_num' : 'paging_num'} key={numberItem}> <a onClick={() => setSelectedPage(numberItem)}>{numberItem}</a> </li> ) } }) return ( [<div className="paging clear martop_20"> <ul> <li className={selectedPage !== 1 ? 'paging_first on' : 'paging_first'} key={'first'}> <a style={selectedPage !== 1 ? { cursor: 'pointer' } : { cursor: 'default' }} onClick={() => setSelectedPage(1)} /> </li> <li className={selectedPage !== 1 ? 'paging_prev on' : 'paging_prev'} key={'prev'}> <a style={selectedPage !== 1 ? { cursor: 'pointer' } : { cursor: 'default' }} onClick={selectedPage !== 1 ? () => setSelectedPage(selectedPage - 1) : null} /> </li> {pagingComponent(currentBundle)} <li className={pageNumber.length === selectedPage ? 'paging_next' : 'paging_next on'} key={'next'}> <a style={pageNumber.length === selectedPage ? { cursor: 'default' } : { cursor: 'pointer' }} onClick={pageNumber.length === selectedPage ? null : () => setSelectedPage(selectedPage + 1)} /> </li> <li className={pageNumber.length === selectedPage ? 'paging_last' : 'paging_last on'} key={'last'}> <a style={pageNumber.length === selectedPage ? { cursor: 'default' } : { cursor: 'pointer' }} onClick={pageNumber.length === selectedPage ? null : () => setSelectedPage(pageNumber.length)} /> </li> </ul> </div>, setTotalSize, size, selectedPage] ) } export default usePage
언젠가 작성했던 Page Hook이다.
해당 훅은
화면에서 보면 이렇게 생겼다.
state를 통해 현재 페이지와 한 페이지 안에 들어갈 레코드 수, 한 번들안에서 보여줄 최대 페이지의 개수등을 관리한다.
그냥 그런 로직이다. 퍼블리싱이 잘 되어서 별다른 로직은 필요가 없었지만 state만 바꿔주는 코드량도 만만치 않게길긴해서 페이징을 쓰는 화면마다 도저히 붙일 수 가 없을 것 같아 hook으로 처리하였다.
실제 코드에서 page를 쓰려면
const [pagingComponent, setTotalSize, size, selectedPage] = usePage() useEffect(()=> { //페이지가 바뀔때 로직처리 },[selectedPage, size])
이게 끝이다.
불필요한 중복 코드 작성을 최소화하며, 리액트를 리액트답게 쓸 수 있는 좋은 기능이라 생각하여
굉장히 애용하고있다.
'Web > Front-End' 카테고리의 다른 글
[React] Infinity Scroll 구현 (0) 2021.05.20 [React] 조건에 따른 컴포넌트 교체 (0) 2021.03.19 [React] 정해진 횟수 연속 클릭 구현 (0) 2021.03.11 [React] 같은 계층의 중첩 라우터끼리 페이지 이동 (0) 2021.03.11 [React ]추천 검색어 구현 (0) 2021.03.11