React는 계속 업데이트되는 오픈소스 라이브러리다.
1) React 18 버전은 더이상 ReactDOM.render를 지원하지 않는다
이전의 index.js
const rootElement = document.getElementById("root");
ReactDOM.render(<AppTest />, rootElement)
이제는 createRoot API를 사용한다.
import {createRoot} from "react-dom/client"
const rootElement = document.getElementById("root")
const root = createRoot(rootElement)
root.render(
<App />
)
2) Concurrent Feature
Suspense 기능을 이용해 독립적으로 렌더링을 할 수 있도록 했다.
대부분 react 앱들은 Webpack, Rollup 과 같은 툴을 사용해 번들링을 한다. html웹 페이지에 js를 쉽게 추가할 수 있기 때문이다. 번들된 앱은 모든 js가 한곳에 있기 때문에 설정하는데 필요한 호출 수가 적은 링크 하나만 필요하게 된다. 이 방법은 과거에는 무리가 없었다. 모던 웹 이전의 웹 js코드는 최소한의 수준으로 작성됐기 때문이다.
모던웹으로 발전하면서 점점 DOM을 다루는 정도가 정교해지면 JS 코드 자체가 방대해지고 무거워졌다.
번들을 나눈뒤 필요한 코드만 불러오면 어떨까???
1) lodash 라이브러리 전체를 불러와서 그 안에 들은 메소드 꺼낸 방식
import _ from 'lodash';
_.find([])
2) lodash의 메소드 중 하나를 불러와 쓰는 방식 (이게 좋아!!!)
import find from 'lodash/find'
find([])
react는 SPA라, 사용하지 않는 모든 컴포넌트까지 한번에 불러온다
=> 첫 화면이 렌더링 될때까지의 시간이 오래걸린다.
=> 코드분할 개념을 도입해보자! (사용하지 않는 컴포넌트는 나중에 불러와~)
React에서 코드 분할하는 방법 2가지
/* 기존에는 파일의 최상위에서 import 지시자를 이용해 라이브러리 및 파일을 불러왔습니다. */
import moduleA from "library"
form.addEventListener("submit", e => {
e.preventDefault();
someFunction();
});
const someFunction = () => {
/* 그리고 코드 중간에서 불러온 파일을 사용했습니다. */
form.addEventListener("submit", e => {
e.preventDefault();
/* 동적 불러오기는 이런 식으로 코드의 중간에 불러올 수 있게 됩니다. */
import('library.moduleA')
.then(module => module.default)
.then(someFunction())
.catch(handleError());
});
const someFunction = () => {
/* moduleA를 여기서 사용합니다. */
}
import Component from './Component';
/* React.lazy로 dynamic import를 감쌉니다. */
const Component = React.lazy(() => import('./Component'));
/* 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>
);
}
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>
);