React 심화 2 - Custom Hook

jeongjwon·2023년 5월 22일
0

SEB FE

목록 보기
49/56

Custom Hook

React 를 이용하여 개발하는 경우에 다른 컴포넌트이지만 같은 로직을 이용하는 것을 많이 경험해보았을 것이다. React 는 함수형 컴포넌트를 통해 반복되는 훅 활용 메서드를 하나로 통일하고 줄임으로써 더 간결하고 명료하게 상태관리 로직을 재활용할 수 있다.

사용하기 앞서 Custom Hook 에는 naming 규칙이 있다.

  • 함수 이름 앞에 꼭 use 를 사용한다.
  • 조건부 함수가 아니어야 하고, return 값을 반환해야한다.

활용

지난 솔로프로젝트에서는 API 를 이용하여 products 를 불러오는 API 를 매 페이지마다 코드를 작성해야 했다.

 useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await axios.get(
          "http://cozshopping.codestates-seb.link/api/v1/products?count=4"
        );
        setItems(res.data);
      } catch (error) {
        setError("데이터를 가져오는 도중에 에러가 발생했습니다.");
        console.log(error);
      }
    };
    fetchData();
  }, []);

이런 코드를 Custom Hook 을 이용해 하나의 파일로 통일하여 사용할 수 있다.

//useFetch.js
import { useState, useEffect } from "react";
import axios from "axios";

export const useFetch = (url) => {
  const [data, setData] = useState([]);
  const [error, setError] = useState(false);
  
useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await axios.get(url)
        setData(res.data);
      } catch (error) {
        setError("데이터를 가져오는 도중에 에러가 발생했습니다.");
        console.log(error);
      }
    };
    fetchData();
  }, []);
  return [data, error];
}

//useFetch 를 사용할 컴포넌트
import useFetch from "useFetch";

function App() {
 //~생략
  const url = `...`;
  const [data, error] = useFetch(url);
  
  //...
}

다시 정리하자면, 동일한 로직을 불필요하게 여러 컴포넌트에서 여러 번 쓰는 것은 메모리를 불필요하게 낭비시키는 것뿐만 아니라 코드를 더 길게 지게함으로써 보기 좋지 못한 코드가 될 수 있다.
Custom Hook 을 이용하여

  • 상태관리 로직의 재활용이 가능하고
  • 클래스 컴포넌트보다 적은 양의 코드로 동일한 로직을 구현할 수 있고
  • 함수형으로 작성하기 때문에 보다 명료하다.


코드 분할

React 는 SPA(Single Page Application)으로 첫 렌더링을 할 때, 필요하지 않는 컴포넌트까지 한 번에 불러오기 때문에 시간이 꽤 걸린다. 꼭 코드 파일의 최상단에서 import 한 컴포넌트를 정적 static 으로 불러오는 방법을 사용했다. 하지만, 동적 dynamic 으로 불러와 필요할 때만 불러와 공간과 시간을 효율적으로 사용할 수 있는 방법인 React.lazySuspense 가 있다.

React.lazy() , React.Suspense

두 가지 React 메서드는 꼭 함께 사용되어야 하고, 동적으로 불러옴으로써 첫 렌더링 지연시간을 줄이는 역할을 한다.
React.lazy() 는 사용할 컴포넌트를 동적으로 import 한다는 의미로 사용된다.
Suspense 는 Router 를 이용해 해당 path 들로 컴포넌트가 나뉘어지기 전 로딩하는 시간에 자동적으로 아직 컴포넌트가 렌더링이 준비되지 않으면 로딩화면을 나타내고, 로딩이 완료되면 컴포넌트를 보여주는 기능을 한다. 이는 굳이 사용자가 로딩 컴포넌트를 작성할 필요가 없어 편리하다.

//App.js -> 페이지를 분기하는 작업에서 적용시키는 것이 좋다
import { Suspense, lazy } from "react";
import { BrowserRouter , Routes, Route } from "react-router-dom";

//React.lazy로 import를 감싼다.
const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));
const Loading = lazy(() => import('/Loading'));

const App = () => {
  
  return(
    
  	<BrowserRouter>
    	<Suspense fallback={<Loading/>}>
    	//fallback 속성에서 Loading 화면으로 사용할 컴포넌트를 설정해준다.
    		<Routes>
    			<Route path="/" element={<Home/>}/>
                <Route path="/about" element={<About/>}/>
    		</Routes>
    	</Suspense>
    </BrowserRouter>
  )
}

0개의 댓글