특정 로직 데이터(ex.데이터를 불러오고, 로딩과 에러 띄우기)를 여러 곳에 재사용하고 싶으면 뭐다?
Custom Hook을 만들어 사용하면 된다!!
커스텀훅을 만들 땐 함수명을 무조건 use로 시작한다!
use를 쓰지 않는다고 해서 에러가 나는 건 아니지만, 재사용 가능한 훅을 만드는 거라면 use를 써주는게 스타일가이드!
일반 컴포넌트와 커스텀훅의 다른 점은
일반 컴포넌트는 React에게 전달해줄 UI jsx를 리턴하는 반면,
커스텀훅은 외부와 공유하고 싶은 데이터를 리턴하면 된다!
use-products.jsx(커스텀훅)
import { useEffect, useState } from "react";
export default function useProducts({ isSales }) {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
useEffect(() => {
setLoading(true);
setError(undefined);
fetch(`data/${isSales ? "sale_" : ""}products.json`)
.then((res) => res.json())
.then((data) => {
console.log("🔥뜨끈한 데이터를 네트워크에서 받아옴");
setProducts(data);
})
.catch((e) => setError("Error!"))
.finally(() => setLoading(false));
return () => {
console.log("🧹 깨끗하게 청소하는 일들을 합니다.");
};
}, [isSales]);
return [loading, error, products];
}
useProducts
가 호출이 되면 처음으로 state를 사용해서 데이터를 초기화 할 것이고, 처음으로 mount 될 때 useEffect
가 실행 될 것이고, 외부에서 checked
가 변경이 될 때(sale인지 아닌지에 따라) 네트워크 통신이 달라져야 하므로 외부로부터 props를 주입 받듯이 데이터를 주입 받을 수 있다. 그래서
export default function useProducts({ isSales })
이렇게 isSales
라는 boolean
값을 외부로부터 받아오는 것이다.
return 할 때는 useState
가 배열을 반환해 주는 것처럼 내가 원하는 데이터들을 반환해 주는 것이다!
그리고!
Products.jsx
const [loading, error, products] = useProducts({ isSales: checked });
이렇게 useProducts
를 사용해서 각각의 데이터를 받아오고, isSales
인지 아닌지 전달해줘야 한다. 그건 AppProducts.jsx의 checked
에 들어있기 때문에 props로 isSales
인지 아닌지를 checked
라는 상태값으로 전달한다!
‼️📣
커스텀훅도 단순히 함수이다. 그래서 전체 컴포넌트가 리랜더링되면 커스텀훅도 당연히 다시 실행된다.
다만 커스텀훅 안에 있는 hook들은 컴포넌트 생애주기에 따라 촥촥 붙어있다고 생각하면 된다.
즉 커스텀훅 내부에 훅들은 각각의 dependency or 컴포넌트 생명주기에 따라 움직인다고 생각하면 된다.
커스텀훅이 재실행 되었다고 해서 내가 이미 컴포넌트에 붙여놓은 훅들이 재실행되는건 아니다!!!