개발을 하다 보면 가끔 상태 관련 로직을 컴포넌트 간에 재사용하고 싶은 경우가 생깁니다. 이 문제를 해결하기 위한 전통적인 방법이 두 가지 있었는데, higher-order components와 render props가 바로 그것입니다. Custom Hook은 이들 둘과는 달리 컴포넌트 트리에 새 컴포넌트를 추가하지 않고도 이것을 가능하게 해줍니다. -React.js 공식 문서
개발자라면 반복되는 로직을 여러 번 복사 & 붙여넣기하는것이 비효율적이라는 것을 알고있을 것이다.
그렇다면 React에서도 마찬가지로 반복되는 로직을 복사 & 붙여넣기하는 것은 똑같이 비효율적일 것이다.
그래서 우리는 커스텀 훅을 통해 반복되는 로직을 언제든지 재사용할 수 있도록 만들수 있다.
// useFetch.ts
import { useEffect, useState } from "react";
export function useFetch(baseUrl, initialType) {
const [data, setData] = useState(null);
const fetchUrl = (type) => {
fetch(baseUrl + "/" + type)
.then((res) => res.json())
.then((res) => setData(res));
};
useEffect(() => {
fetchUrl(initialType);
}, []);
return {
data
};
}
새로운 파일을 생성해 useFetch
라는 커스텀 훅을 만들었다.
커스텀 훅을 사용할 때 중요한 컨벤션이 있는데
꼭 파일 이름과 함수명은 use로 시작해야한다는 것이다.
이제 이 커스텀훅을 한번 사용해보자.
// App.tsx
import { useFetch } from "./useFetch";
const baseUrl = "https://jsonplaceholder.typicode.com";
function App() {
const { data: userData } = useFetch(baseUrl, "users");
const { data: postData } = useFetch(baseUrl, "posts");
return (
<div>
<h1>User</h1>
{userData && <pre>{JSON.stringify(userData[0], null, 2)}</pre>}
<h1>Post</h1>
{postData && <pre>{JSON.stringify(postData[0], null, 2)}</pre>}
</div>
);
}
export default App;
이처럼 코드의 양도 줄일 수 있어 가독성이 늘어나고,
이 커스텀 훅을 다른 컴포넌트에서도 재활용 가능하기 때문에 동일한 로직을 수행하는 컴포넌트가 많을 경우 커스텀 훅을 더 유용하게 사용할 수 있다.
좌측 바를 땡겨 메뉴를 클릭하거나 새 창에서 열면 useFetch 함수도 수정할 수 있으니 App.tsx와 useFetch.ts를 마음대로 수정해가며 사용하다보면 더 익숙해 질 수 있을 것이다.