Automatic Batching
기존 방식
Automatic Batching 적용
// 기존 버전
setTimeout(() => {
setCount((count) => count + 1);
setIsFull((isFull) => !isFull);
// 각 state의 업데이트 마다 재렌더링이 발생
}, 1000)
// 현재 버전
setTimeout(() => {
setCount((count) => count + 1);
setIsFull((isFull) => !isFull);
// 재렌더링이 마지막에 한 번만 발생 (Automatic Batching)
}, 1000);
Transitions
긴급한 업데이트와 긴급하지 않은 업데이트를 구분해서 처리하기 위한 개념
업데이트의 종류
- 긴급한 업데이트
- 사용자와 직접적인 인터랙션이 일어나는 경우
- 예) 글자 입력, 버튼 클릭 등
- 긴급하지 않은 업데이트
- 사용자와 직접적인 인터랙션이 일어나지 않는 경우
- 예) 서버로부터 결과를 받아와서 보여주는 경우
import { startTransition } from "react";
// 긴급 업데이트: 입력한 글자를 화면에 보여주어야 함
setInputValue(input);
// 함수 내에 있는 모든 업데이트는 Transition 업데이트가 됨
startTransition(() => {
// Transition 업데이트: 검색 결과를 보여주어야 함
setSearchQuery(input);
});
Suspense
하위 컴포넌트(children)가 준비되기 전까지 렌더링을 중단하는 것
웹사이트 규모 ↑ / 컴포넌트 사이즈 ↑ / 로딩 시간 ↑
Code Splitting
Lazy Loading / Dynamic Loading
import { lazy, Suspense } from "react";
import LoadingSpinner from './LoadingSpinner';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent(props) {
return (
<Suspense fallback={LoadingSpinner />}>
<OtherComponent />
</Suspense>
);
}
export default MyComponent;
// OtherComponent가 준비되기 전까지
// fallback 속성에 들어가있는 LoadingSpinner라는 컴포넌트를 화면에 보여주고
// OtherComponent가 준비되면 그때 OtherComponent를 보여줌
클라이언트와 서버 렌더링 API 업데이트
리액트 DOM 클라이언트 변경사항
기존방식 (리액트 버전17)
import React from "react";
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
새로운 방식 (리액트 버전 18)
import React from "react"
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
리액트 DOM 서버
- renderToPipeableStream
- NodeJS 환경에서 스트리밍을 위한 함수
- renderToReadableStream
- Edge runtime 환경(예: Deno, Cloudflare workers)을 위한 함수
새로운 Strict 모드 작동 방식
Strict Mode
언마운트(unmount) 시켰다가 다시 한 번 마운트(mount) 시킴
컴포넌트 생명주기 함수들이 예상과 다르게 여러번 호출 될 수 있음
새롭게 추가된 훅들
useId()
서버와 클라이언트에서 고유한 id값을 생성하기 위한 hook
list rendering시 map함수 내에서 반환하는 element key사용 용도는 아님
import { useId } from 'react';
function MyComponent() {
const id = useId();
return (
<div>
<label htmlFor={id}>이름:</label>
<input id={id} type="text" />
</div>
);
}
useTransitions()
긴급하지 않은 update를 위한 hook
import { useState, useTransition } from 'react';
function MyComponent() {
const [isPending, startTransition] = useTransition();
const [count, setCount] = useState(0);
const handleClick = () => {
startTransition(() => {
setCount(count + 1);
});
};
return (
<div>
<button onClick={handleClick}>카운트 증가</button>
{isPending ? <p>업데이트 중...</p> : <p>카운트: {count}</p>}
</div>
);
}
useDeferredValue()
긴급하지 않은 update를 재렌더링 하는것을 연기할 수 있게 해주는 hook
짧은 시간에 한 가지 상태의 update가 여러번 발생 했을 경우 최종 상태값만 update하면 됨 (debouncing)
지연된 렌더링은 중단 가능하며 사용자의 입력을 차단하지 않음
import { useState, useDeferredValue } from 'react';
function MyComponent() {
const [text, setText] = useState('');
const deferredText = useDeferredValue(text);
const handleChange = (e) => {
setText(e.target.value);
};
return (
<div>
<input type="text" value={text} onChange={handleChange} />
<p>입력한 텍스트: {deferredText}</p>
</div>
);
}
useSyncExternalStore()
외부 저장소를 구독 할 수 있게 해주는 hook
import { useSyncExternalStore } from 'react';
function useMyStore(selector) {
return useSyncExternalStore(
myStore.subscribe,
() => selector(myStore.getState()),
() => selector(myStore.getSnapshot())
);
}
useInsertionEffect()
CSS-in-JS 라이브러리를 위한 hook
렌더링 과정에서 스타일 삽입의 성능 문제를 해결 할 수 있게 해줌
import { useInsertionEffect } from 'react';
function MyComponent() {
useInsertionEffect(() => {
const style = document.createElement('style');
style.textContent = `
.my-class {
color: red;
}
`;
document.head.appendChild(style);
return () => {
document.head.removeChild(style);
};
}, []);
return <div className="my-class">안녕하세요, 세계!</div>;
}
'FrontEnd > React' 카테고리의 다른 글
연차 관리 캘린더 프로젝트 With ChatGpt #1 (0) | 2024.06.13 |
---|---|
연차 관리 캘린더 프로젝트 With ChatGpt #0 (1) | 2024.06.04 |
Mini Project (0) | 2024.05.21 |
Styling (0) | 2024.05.08 |
Context (0) | 2024.04.30 |