앞에서 만든 별 버튼을 클릭했을 때 앱이 바로 반응하지 않는 것을 확인할 수 있다.
실제 환경에서 사용할 수 있도록 network latency를 추가해보자.
사용자에게 피드백을 주기 위해 fetcher.state
을 이용해 별을 loading state로 만들 수 있다.
이러한 전략을 "Optimistic UI" 라고 부른다.
fetcher는 action에 제출하는 form data를 가지고 있으므로, fetcher.formData
를 사용할 수 있다.
이를 이용해 네트워크가 완료되지 않았더라도 즉시 별의 상태를 업데이트 할 수 있다.
만약 업데이트가 실패하면 UI가 실제 데이터로 돌아간다.
// 📄src/routes/contact.jsx
// existing code
function Favorite({ contact }) {
const fetcher = useFetcher();
let favorite = contact.favorite;
if (fetcher.formData) {
favorite = fetcher.formData.get("favorite") === "true";
}
return (
<fetcher.Form method="post">
<button
name="favorite"
value={favorite ? "false" : "true"}
aria-label={
favorite
? "Remove from favorites"
: "Add to favorites"
}
>
{favorite ? "★" : "☆"}
</button>
</fetcher.Form>
);
}
별 버튼을 클릭하면 즉시 상태가 변하는 것을 볼 수 있다.
실제 데이터를 랜더링하는 대신 fetcher에 제출되는 formData가 있는지 확인하고 있다면 그걸로 대신한다.
action이 완료되면, fetcher.formData
는 사라지게 되며 실제 데이터를 다시 사용한다.
따라서 Optimistic UI코드에 의해 버그가 발생하더라도 결국엔 올바른 상태로 돌아간다.
출처 : 리액트 라우터 공식 홈페이지➡️