-
React) 클릭하면 특정 div로 스크롤 이동하는 hook 만들어보기Web/React.JS 2022. 2. 27. 23:40
지금 쇼핑몰 프로젝트를 하고 있는데 구현하고 싶은 기능이 있다.
이렇게 생긴 버튼을 클릭하면 해당 부분으로 스크롤을 자동으로 움직여주는 기능이다.
거의 모든 쇼핑몰에서 사용하고 있길래 이번 프로젝트에서 적용해 보았다.
첨에는 쉽지 않겠다... 싶었는데
찾아보니 useRef에 구현해놓은 메서드가 이미 존재했다
(https://developer.mozilla.org/ko/docs/Web/API/Element/scrollIntoView)
element.scroolIntoView라는 메서드였다.
바로 useMoveScroll라는 hook을 만들어 활용해 보았다.
import { useRef } from 'react'; //hook function useMoveScrool() { const element = useRef<HTMLDivElement>(null); const onMoveToElement = () => { element.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }; return { element, onMoveToElement}; } export default useMoveScrool;
behavior : 애니매이션을 사용할지 말지 선택함
block : 클릭할시 어디에 사용자 스크롤을 위치시킬 건지 정함.
"start", "center", "end", "nearest"중 하나 선택. 기본값은 "start".
cosnt {element, onMoveToElement} = useMoveScrool() return ( <> <div onClick={onMoveToElement}> 이걸 누르면? </div> <div ref={element}> 여기로 옵니다. </div> </> )
실제로 작동하기는 한다.
여기서 문제점은 만들 버튼이 3개가 있고 더 늘어날 수도 있다는 점이다.
cosnt [element1, onMoveToElement1] = useMoveScrool() cosnt [element2, onMoveToElement2] = useMoveScrool() cosnt [element3, onMoveToElement3] = useMoveScrool()
이런 식으로 하드코딩하는 건 피하고 싶어서
hook을 배열처럼 사용하는 방법을 고민하다가
이 게시글에서 썻던 '유사 배열'을 사용하면 줄일 수 있지 않을까 생각이 돼서 적용해보았다.
const goodsTabs = { 0: useMoveScrool('상품 상세'), 1: useMoveScrool('리뷰'), 2: useMoveScrool('상품 문의'), };
뭔가 해결되어가는 느낌이다.
이제 hook을 배열로 만들어 주었으니
goodsTabs[0].element goodsTabs[0].onMoveToElement
element와 onMove 함수를 요런 식으로 사용할 수 있다.
여기다가 map을 때려 박아서 컴포넌트를 만들면 끝이다 싶었는데
오류가 떳다.
하드코딩을 피하려면 map를 반드시 사용해야 해서
구글링을 해본 결과 유사 배열에 length 항목을 넣고
Array.from()으로 유사 배열을 감싸주면 배열처럼 쓸 수 있다고 한다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/from
결론
const goodsTabs = { 0: useMoveScrool('상품 상세'), 1: useMoveScrool('리뷰'), 2: useMoveScrool('상품 문의'), length: 3, }; return ( <> {Array.from(goodsTabs).map((tab, index) => { <div onClick={tab.onMoveToElement}>{tab.name}</div>; })} <div ref={goodsTabs[0].element}> 상품 상세 </div> <div ref={goodsTabs[1].element}> 리뷰 </div> <div ref={goodsTabs[2].element}> 상품문의 </div> </> )
이 hook은 두고두고 잘 써먹을 거 같다.
'Web > React.JS' 카테고리의 다른 글
리액트 성능 최적화 기법 2 - 자바스크립트 실행 시간 줄이기 (0) 2022.11.15 리액트 성능 최적화 기법 1 - 이미지 최적화 (0) 2022.10.27 Promise.all로 반복되는 API 한번에 모아 보내기 (2) 2022.06.20 React 프로젝트 Vitejs react-ts 로 빌드하기 (2) 2022.05.09 재활용 가능한 Rating component (별점 컴포넌트) (2) 2022.04.03