자신만의 Hook을 만들어 보자

SeongHyeon Bae·2022년 8월 18일
2

문제 상황

지인의 부탁으로 쇼핑몰 제품 정보 관리 페이지를 제작중 문제가 발생하였다.

위와 같이 하나의 제품에는 사진, 제품이름, 영어이름, 중국어이름, 운송장번호 등등 많은 Data값이 존재한다.
이 데이터를 어떤식으로 관리할까 고민하다가 처음에는 아래와 비슷한 방식으로 하나의 상태에 모든 데이터를 넣었었다.

잘못된 방식

const [product, setProduct] = useState([
  {ko:'사다리 모던 진열대',en : 'Ladder modern display', ... ,Hscode:'9403209000',id :'acxz123czxdas'}
  ,{ko:'대왕 거위 모찌 쿠션',en :'Giant goose mochi cushion',...,Hscode:'9403209000',id :'sa5d135zxcsda'}
  ,...]);

처음에는 상위 컴포넌트에서 하나의 상태에 Data를 관리하여 하위 컴포넌트에게 props 전달하는 방식으로 사용하였다. 하지만 data의 양이 점점 늘어날 수록 데이터 변경 시 딜레이가 발생하기 시작했다.

위와 같은 상품 200개가 product 상태 하나에 전부 들어가 있다고 하자. 그럼 200개중 하나의 객체 프로퍼티값을 setProduct를 통해 수정을 하게되면 나머지 199개의 불필요한 중복이 발생하게 된다. 즉, 값이 변경되는 것은 하나의 상품인데 199개의 상품도 동시에 재렌더링이 발생하게 되는 것이다. 왜냐하면 리액트에서는 재렌더링 조건중 하나가 상태값이 변할 경우이기 때문이다. 그러다 보니 유저가 한글자씩 키보드에서 입력할떄마다 0.5~1 초 정도의 딜레이가 생기고 불만이 생긴 것이다.

이것을 해결하기 위해 Custom Hook을 구현하여 데이터 단위를 쪼개어 주었다.

여기서 Hook이란 무엇인지 알고 넘어가 보자.

Hook

Hook은 React 버전 16.8부터 React 요소로 새로 추가되었습니다. Hook을 이용하여 기존 Class 바탕의 코드를 작성할 필요 없이 상태 값과 여러 React의 기능을 사용할 수 있습니다.

React는 클래스형 컴포넌트함수형 컴포넌트로 구현할 수 있다.
클래스형 컴포넌트는 이해하기도 어렵고 클래스 컴포넌트 사이에서 상태로직을 재사용 하기가 어렵다.
함수형태 컴포넌트에서는 비교적 쉽고 간단하기 때문에 선호하지만 이전에는stateLife Cycle을 사용하기 위해선 어쩔수 없이 클래스형 컴포넌트를 사용할 수 밖에 없었다.

하지만 이 문제점을 해결하기 위해서 Hook 이 나온 것이다.
위에서 말한 state를 사용하기 위해서 useState라는 훅을 Life Cycle를 사용하기 위해서 useEffect라는 훅이 생긴 것이다.

즉, 함수형 컴포넌트에서 클래스형 컴포넌트기능을 사용하기 위한 도구라고 보면 될 것 같다.

Custom Hook

그럼 나만의 Hook은 뭘까.

개발을 하다보면 상태 로직이 중복되는 경우가 발생한다.

필자의 경우 위와 같은 데이터를 하나의 컴포넌트로 보면 데이터의 상태와 input box의 onChange로직은 상품 갯수만큼 중복된다고 볼 수 있다.

그래서 아까 같이 하나의 상태에 모든 제품들을 넣는 방식이 아닌 State를 상품마다 독자적으로 만들어 주어야한다.

function useProduct(obj){
	const [product,setProduct] = useState(obj);
 	
 	const onChange = (e) => setProduct(e);
  	//...
  	// 상태 로직 관련 함수들
  
  	return {product, setProduct, onChange}
}

export default useProduct;
// useProduct.js
import useProduct from '../hooks/useProduct';
//ex) obj = {ko:'사다리 모던 진열대',en : 'Ladder modern display', ... ,Hscode:'9403209000'
//,id :'acxz123czxdas'}
function DataRow(obj){
	const {product, setProduct,onChage} = useProduct(obj);
    
  	return <div><input value ={product.ko} onChage={onChage}/></div>
}
// DataRow.js

결론

서버에서 데이터 배열을 받아오고 각각의 데이터 obj를 DataRow 배열에 넣어주면 Row당 상태값이 하나 생기게 된다. 이렇게 Custom Hook을 사용하면 만약 데이터 하나의 값을 변경한다고 할 때 이전 처럼 200개의 데이터가 들어있는 상태를 바꾸는 것이 아닌 하나의 Row에 대한 상태값만 수정되기 때문에 1개의 Row만 렌더링 되어 딜레이를 줄일 수 있었다. 물론 Custom Hook을 사용하지 않고 DataRow.js 파일에 모든 상태를 직접 만들어도 동작은 하겠지만 중복을 줄이기 위해 Custom Hook을 사용하는 것이 좋겠다.

출처

https://ko.reactjs.org/docs/hooks-intro.html

profile
FE 개발자

0개의 댓글