2022. 11. 2. 16:42ㆍFront-end/React
React 16.8 버전에서 Hook이 발표되고 난 후 React에서 컴포넌트를 선언하는 방법의 대세는 클래스 컴포넌트에서 함수 컴포넌트로 옮겨왔다. 많은 사람들이 익숙하고 이미 기존에 많은 코드들이 작성된 방법인 클래스 컴포넌트에서 함수 컴포넌트로 옮겨온 이유 중에는 함수 컴포넌트의 문법이 더 단순하고 교착상태로 인한 버그가 발생하지 않는다는 장점도 있지만, Custom Hook의 편리함과 유용성도 큰 비중을 차지하고 있다.
리액트는 UI를 구축하기 위한 라이브러리로 리액트가 가진 핵심적인 관심사는 UI와 UI를 변경시키는 로직이다. 이 중 UI는 실제 코드상에서는 JSX라는 형태로 표현되고, UI 변경 로직은 유저의 입력에 반응하거나 API를 호출하고 스크린의 변화에 반응하는 등 여러 동작들을 통해서 UI에 영향을 미치는 행위라고 할 수 있다.
Presentational - Container
리액트를 활용하는 개발자들은 리액트의 관심사는 UI와 로직이란 것을 파악하고 이를 분리하기 위해서 여러 기법들을 연구하게 된다. 그중 처음으로 유명해진 기법은 Presentational - Container 패턴으로, 컴포넌트를 크게 두 계층으로 분리하는 방법이다.
Container는 로직들을 다루는 부분으로 UI에는 관여하지 않으며 오로지 UI를 구성하고 변화하기 위한 로직에만 집중하는 컴포넌트이고, Presntational은 반대로 로직은 상관하지 않으며 UI가 어떻게 구성되어야 하는지에만 집중하는 컴포넌트이다. 이렇게 컴포넌트를 두 계층으로 나누어서 Presentational을 Container로 감싼 후 필요한 정보들과 로직을 모두 props로 전달해주는 형태로 설계하는 방법이 Presentatinal - Container 패턴이다.
Presentational - Container 패턴은 Hook이 등장하기 전까지는 리액트에서 관심사를 분리하는 표준 패턴으로 사용되었지만 Hook이 등장한 후에는 많이 사용하지 않는다. 왜냐하면 Custom Hook이란 기법이 발명되었고 이것이 더 효율적으로 관심사를 분리할 수 있다고 판단되었기 때문이다.
Custom Hook
커스텀 훅은 리액트가 기본적으로 제공해주는 훅들을(useState, useEffect 등) 이용해서 만든 함수다. 로직은 UI를 변경시키기 위함이고, 함수형 컴포넌트에서 로직은 대부분 useState, useEffect 등의 Hook을 통해서 구현된다. 훅을 통해서 편리하기 state를 선언하고 effect를 발생시킬 수 있게 되었지만, 컴포넌트 내부에 많은 로직들이 들어가게 되면 컴포넌트가 복잡해지고, 동일한 로직들을 여러 컴포넌트에 걸쳐서 재사용하기 힘들다는 단점이 있었다.
일반적으로 동일한 로직이 보일 경우 함수로 분리해 추출하듯이 리액트에서도 Hook을 이용한 동일한 로직들을 별도의 함수로 추출해서 여러 컴포넌트에 사용하고자 하는 시도가 있었고 그렇게 커스텀 훅이라는 기법이 생겨났다. 커스텀 훅은 리액트의 훅을 호출하는 함수여야 하고, use로 시작해야 한다는 조건이 있다.
Custom Hook 예시
import { useCallback, useEffect, useState } from "react";
const useData = () => {
const [state, setState] = useState(null);
useEffect(() => {
setTimeout(() => {
setState({ hello: "world" });
}, 100);
}, [setState]);
return state;
};
공식문서 참고하기
'Front-end > React' 카테고리의 다른 글
Next.js가 서버 사이드 렌더링 React 앱의 미래인 5가지 이유 (0) | 2022.11.11 |
---|---|
[React] Context API (0) | 2022.10.31 |
[React] 리액트 앱에서 렌더링 최적화하기 (0) | 2022.10.30 |
[React] 리액트에서 CSR을 최적화하는 원리 (0) | 2022.10.03 |
[React] CRA를 이용한 프로젝트 생성과 TypeScript 적용하기 (0) | 2022.09.15 |