[개발자되기: React 심화2] Day-52

Kyoorim LEE·2022년 7월 28일
0

Custom Hooks

Custom Hook 정의 시 지켜야 할 규칙

  • 함수 이름 앞에 use 붙이기
  • 프로젝트 내 hooks 디렉토리에 Custom Hook 위치시키기
  • return 하는 값은 조건부이면 안됨

React에서 주목해야할 기능

React 18 버전에서는 더이상 ReactDOM.render를 지원하지 않음

REACT 18 이전의 index.js

const rootElement = document.getElementById("root");
ReactDOM.render(<AppTest />, rootElement);

바뀐 index.js

React 18에서는 이제 createRoot API를 사용함

import { createRoot } from "react-dom/client";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
    <App />
);

Code Spliting 코드 분할

💡 어느 페이지에서 코드를 해석/실행 했을 때 느려지는지 파악해서 번들을 나눈 뒤에 지금 필요한 코드만 불러오고 나중에 필요한 코드는 나중에 불러오면 어떨까?

코드 분할의 핵심: 번들이 거대해지는 것을 방지하기 위해 번들을 물리적으로 나누기

번들 분할/ 번들 줄이기

npm을 통해 다운받는 3rd party 라이브러리는 다양한 메소드를 제공하는 만큼 코드의 양이 많고 번들링 시 공간을 많이 차지함

사용 중인 라이브러리를 전부 불러와서 사용하는 것보다 개별적으로 불러오게 되면 많은 공간을 차지하지 않음

lodash 라이브러리 import 예시

/* 이렇게 lodash 라이브러리를 전체를 불러와서 그 안에 들은 메소드를 꺼내 쓰는 것은 비효율적입니다.*/
import _ from 'lodash';

...

_.find([]);

/* 이렇게 lodash의 메소드 중 하나를 불러와 쓰는 것이 앱의 성능에 더 좋습니다.*/
import find from 'lodash/find';

find([]);3

React에서의 코드분할

정적 불러오기(static import) - 기존 방법

코드 파일 가장 최상위에서 import 지시자를 이용해 불러오는 방법

/* 기존에는 파일의 최상위에서 import 지시자를 이용해 라이브러리 및 파일을 불러왔습니다. */
import moduleA from "library";

form.addEventListener("submit", e => {
  e.preventDefault();
  someFunction();
});

const someFunction = () => {
  /* 그리고 코드 중간에서 불러온 파일을 사용했습니다. */
}

동적 불러오기(dynamic import)

구문 분석 및 컴파일해야하는 스크립트 양을 최소화하기위해 지원하는 import 방법
https://xtring-dev.tistory.com/24

React.lazy와 함께 사용할 수 있음

form.addEventListener("submit", e => {
  e.preventDefault();
	/* 동적 불러오기는 이런 식으로 코드의 중간에 불러올 수 있게 됩니다. */
  import('library.moduleA')
    .then(module => module.default)
    .then(someFunction())
    .catch(handleError());
});

const someFunction = () => {
    /* moduleA를 여기서 사용합니다. */
}

React.lazy()

React.lazy() 함수를 사용해 dynamic import를 사용할 수 있음
=> 초기 렌더링 지연시간을 줄일 수 있음

import Component from './Component';

/* React.lazy로 dynamic import를 감쌉니다. */
const Component = React.lazy(() => import('./Component'));

React.lazy로 감싼 컴포넌트의 경우 단독으로 쓰일 수는 없고 React.suspense 컴포넌트 하위에서 렌더링 해야함

React.Suspense

아직 렌더링이 준비되지 않은 컴포넌트가 있을 때 로딩 화면을 보여주고, 로딩이 완료되면 렌더링이 준비된 컴포넌트를 보여주는 기능

Suspense 컴포넌트 하나로 여러개의 lazy 컴포넌트 보여줄 수 있음

/* suspense 기능을 사용하기 위해서는 import 해와야 합니다. */
import { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
			{/* 이런 식으로 React.lazy로 감싼 컴포넌트를 Suspense 컴포넌트의 하위에 렌더링합니다. */}
      <Suspense fallback={<div>Loading...</div>}>
				{/* Suspense 컴포넌트 하위에 여러 개의 lazy 컴포넌트를 렌더링시킬 수 있습니다. */}
        <OtherComponent />
				<AnotherComponent />
      </Suspense>
    </div>
  );
}

React.lazy와 Suspense의 적용

웹페이지를 불러오고 진입하는 단계인 Route에 lazy와 Suspense 기능을 적용시키는 것이 좋음

초기 렌더링 시간은 줄어드나 페이지 이동 시 계속 로딩화면이 보여지기 때문에 (fallback) 서비스에 따라 적용여부 결정해야 함

import { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);
profile
oneThing

0개의 댓글