
18.2와 동일하지만, 리액트 19로의 업그레이드를 위한 사항이 추가된 버전
규칙에 따라 비동기 전환을 사용하는 함수
-> 보류중인 상태, 오류, 낙관적 업데이트 자동처를 위해 전환시 비동기 함수를 사용할 수 있게 되었다!
react 19 이전 코드
function UpdateName({}) {
const [name, setName] = useState("");
const [error, setError] = useState(null);
const [isPending, setIsPending] = useState(false);
const handleSubmit = async () => {
setIsPending(true);
const error = await updateName(name);
setIsPending(false);
if (error) {
setError(error);
return;
}
redirect("/path");
};
return (
<div>
<input value={name} onChange={(event) => setName(event.target.value)} />
<button onClick={handleSubmit} disabled={isPending}>
Update
</button>
{error && <p>{error}</p>}
</div>
);
}
Actions의 일반적인 경우를 처리.
내부에 넣은 액션 함수는 래핑되어 submitAction으로 반환된다.
import { useActionState } from 'react';
import { action } from './actions.js';
//초기값, 현재값 둘다 props로 받음
function action(currentState, formData) {
// ...
return 'next state';
}
function MyComponent() {
const [state, formAction, isPending] = useActionState(action, null);
// SSR에서 하이드레이션이 끝나지 않았더라도 isPending을 이용하여 UI를 업데이트 가능
return (
<form action={formAction}>
{/* ... */}
</form>
);
}
action속성에 액션 함수를 전달하면 자동으로 연결된다!
-> 제출 후 양식이 자동으로 재설정된다!
마지막 폼 제출의 상태 정보를 제공
-> form 내부에 렌더링한 컴포넌트에서 호출해야함! (최상위x)
-> 바로 상위 form에 대한 상태 정보만 반환한다!
import {useFormStatus} from 'react-dom';
function Submit() {
// 현재 상태, 제출한 데이터, get이나 post, 상위 form에 전달한 함수
const { pending, data, method, action } = useFormStatus();
return <button disabled={pending}>Submit</button>
}
export default function App() {
return (
<form action={action}>
<Submit />
</form>
);
}
비동기 요청이 진행되는 동안 최종 상태를 낙관적으로 표시
-> 실제로 작업을 완료하는 데 시간이 걸리더라도 사용자에게 즉시 작업의 결과를 표시할 수 있음!
낙관적 업데이트
서버로부터 실제 응답을 받기 전에 UI를 미리 업데이트하는 기법
-> 오류 발생시 낙관적 업데이트를 원래 값으로 자동으로 되돌림
-> 즉각적인 피드백 가능
import { useOptimistic } from 'react';
function AppContainer() {
const [optimisticState, addOptimistic] = useOptimistic(initialState, updateFn);
);
const updateFn = (currentState, optimisticValue) => {
}
const initialState = null;
}
낙관적으로 사용할 값
작업이 대기 중 -> state와 동일
작업이 대기 아님 -> updateFn에서 반환된 값과 동일
낙관적 업데이트가 있을 떄 호출하는 디스패치 함수
인자로 optimisticValue를 받아, updateFn 함수를 호출한다
// 현재 상태
let state = {
comments: ["First comment", "Second comment"],
};
// 상태를 업데이트하는 함수
function updateFn(state, optimisticValue) {
// 낙관적으로 새 댓글을 추가
return {
...state,
comments: [...state.comments, optimisticValue],
};
}
// addOptimistic 구현
function addOptimistic(optimisticValue) {
state = updateFn(state, optimisticValue); // 상태 업데이트
console.log("Updated state:", state); // 새로운 상태 출력
}
// 사용자가 새 댓글을 추가했을 때
addOptimistic("New comment");
// 결과
// Updated state: { comments: ["First comment", "Second comment", "New comment"] }
오.. 이제 헬멧을 안 써도 됨!
-> head section과 관련된 사항은 자동으로 문서 head 섹션으로 끌어올린다!
function BlogPost({post}) {
return (
<article>
<h1>{post.title}</h1>
<title>{post.title}</title>
<meta name="author" content="Josh" />
<link rel="author" href="https://twitter.com/joshcstory/" />
<meta name="keywords" content={post.keywords} />
<p>
Eee equals em-see-squared...
</p>
</article>
);
}
import { prefetchDNS, preconnect, preload, preinit } from 'react-dom'
function MyComponent() {
preinit('https://.../script.js', {as: 'script' })
preload('https://.../font.woff', { as: 'font' })
preload('https://.../stylesheet.css', { as: 'style' })
prefetchDNS('https://...')
preconnect('https://...')
}
React가 복구 가능한 오류를 감지했을 때 호출
Error Boundary에 의해 잡히지 않은 오류 (앱 전체 중단 가능성o)
window.reportError에 보고됨
Error Boundary에 의해 잡힌 오류
console.error에 보고됨
const root = createRoot(container, {
onRecoverableError: (error) => {
console.warn("Recoverable error:", error);
},
onUncaughtError: (error, errorInfo) => {
// ... 에러 리포트 로그
},
onCaughtError: (error, errorInfo) => {
// ... 에러 리포트 로그
},
});
React의 에러 처리 흐름
- 오류 발생 → React가 오류를 감지.
- Error Boundary 확인
a. Error Boundary가 오류를 잡음: onCaughtError 호출
b. Error Boundary가 없음: onUncaughtError 호출- React가 복구 가능시 onRecoverableError 호출
개발 환경에서 Strict Mode로 인한 이중 렌더링이 발생할 때,
두 번째 렌더링에서 첫 번째 렌더링의 메모이제이션된 결과를 재사용하게 바뀜!
컴포넌트가 Suspense 상태(예: 데이터 로딩 중)가 되면
-> 중단된 컴포넌트의 형제 컴포넌트들이 먼저 렌더링된다!
-> 형제 컴포넌트 렌더링이 끝나면, Suspense 경계의 fallback UI 표시
-> 즉, 형제 트리 전체 렌더링이 완료한 후에 fallback UI를 보여줬음.
Suspense 상태가 되면
-> 즉시 fallback UI가 표시
-> 이후 Suspense 경계 안 형제 컴포넌트들이 백그라운드에서 스케줄링 및 렌더링
-> 렌더링이 끝나면 fallback UI가 최종 콘텐츠로 대체