목차
리액트 액션
액션(Action)은 리액트 19에서도입된 새로운 비동기 작업 처리 방식이다. 폼이나 버튼 등에서 서버와 데이터를 주고받는 작업을 더 쉽고 안전하게 구현하도록 설계되었다. 기존에 비동기 작업을 처리할 때 직접 loading, error, data 상태를 관리해야 해서 코드가 복잡해지고 실수할 여지도 많았는데, 액션이 도입되면서 폼의 action 속성에 액션 함수를 직접 전달할 수 있게 되었다. 액션 함수는 폼 데이터(FormData)를 받아 비동기 작업을 처리한다. 리액트가 자동으로 로딩, 에러, 완료 상태를 관리해 줘서 이제는 핵심 로직에만 집중하면 된다.
액션은 폼(Form)에 자주 사용된다. 전통적으로 HTML 폼의 action 속성에는 URL(문자 값)이 사용되었지만, 리액트 19 버전부터는 action 속성에 액션을 처리하는 함수(funciton)를 설정할 수 있게 됐다. 액션 함수 안에서 비동기 작업을 손쉽게 처리할 수 있다.
export default function MyForm() {
// 액션 함수 : form 데이터를 받아 비동기 작업 처리
const handleAction = async (formData) => {
// 1.5초 대기
await wait(1.5)
// 콘솔 패널에 입력값 출력
console.log(formData.get('name'))
}
return (
<form action={handleAction}>
<label htmlFor="name" className="sr-only">이름</label>
<input type="text" name="name" id="name" />
<button type="submit">제출</button>
</form>
)
}
function wait(delay = 1) {
return new Promise((resolve) => setTimeout(resolve, delay * 1000))
}
액션은 UI 업데이트의 우선순위를 조절해 주는 기능인 트랜지션(Transition)과도 자연스럽게 연결된다. 액션을 전환과 함께 사용하면 비동기 작업이 진행되는 동안 UI가 멈추지 않고 부드럽게 작동한다.
useActionState 훅
리액트 19의 useActionState, useFormStatus 훅을 활용하면 폼과 비동기 작업이 훨씬 간단해진다. 더 적은 코드로 더 명확하게 상태를 관리할 수 있고, 로딩, 에러, 데이터 상태를 자동으로 처리해 주어 복잡한 폼도 쉽게 구현할 수 있다. 비동기 함수의 첫 번째 매개변수는 이전 상태, 두 번째는 폼 데이터다. useAcitonState 훅의 두 번째 인수로 상태 초기값을 전달할 수 있다. 폼을 제출한 후에 입력 값이 자동으로 초기화되어서 입력 값을 계속 유지하려면 별도의 상태 관리가 필요하다.
useOptimistic 훅
낙관적 업데이트(Optimistic Update)는 서버에 데이터가 저장되기를 기다리지 않고 사용자에게 먼저 낙관적인 결과를 보여주는 방식이다. 서버에 요청을 보내고 응답을 받기까지 시간이 걸리는데, 이때 사용자가 결과를기다리면 UI가느릭ㅔ반응하는 느낌을 받을 수 있다. 하지만 낙관적 업데이트를 적용하면 사용자가 즉시 결과를 볼 수 있어서 훨씬 쾌적한 사용자 경험을 제공할 수 있다.
useOptimistic 훅을 사용하면 실제 서버 응답과 관계 없이 메시지가 UI에 즉시 추가된다. 메시지 객체에 pending: true를 붙이면 전송 중 상태를 표시할 수 있다. 서버 응답이 오면 실제 메시지 목록으로 업데이트한다. 실패하면 추가된 메시지를 제거한다.
낙관적 업데이트를 사용했을 때 장점은 즉각적인 UI 반응으로 사용자 만족도가 높아지고 서버 응답 지연이 사용자 경험에 미치는 영향을 최소화할 수 있다는 것이다. 하지만 고려해야 할 것이 있다. 서버에서 오류가 발생하면 UI에서 낙관적으로 추가한 데이터를 반드시 제거하거나 오류를 알릴 수 있어야 한다.
오늘 하루를 돌아보며
오늘 실습 시간에는 리액트 액션과 useOptimistic 훅을 사용해서 할 일 목록(Todo List) 앱을 리팩토링했다. 낙관적 업데이트가 반영되니 즉각적인 피드백을 경험할 수 있었고, 서버 요청에 실패해도 자동으로 UI가 원래대로 돌아갔다. 낙관적 업데이트가 사용자 경험에 얼마나 중요한 역할을 하는지 직접 확인해 볼 수 있었다.