Optimistic UI란
우선 시작하기에 앞서 Optimistic UI의 개념에 대해 짚고 넘어가겠습니다
Optimistic UI는 서버의 응답을 기다리지 않고 즉시 UI적인 반응을 보이는 것입니다. 쉽게 말해서 서버에 응답이 이미 성공했을 것이라고 가정하고 UI를 그리는 방식을 일컫는 말이라는 것입니다.
어떤 요청이 높은 확률로 성공한다는 보장이 있을 때, 그 요청이 늦지 않은 시간 안에 응답이 온다는 보장이 있을 때 사용할 수 있는 UI라고 생각하시면 됩니다.
이러한 Optimistic UI를 이용하여 댓글 기능을 구현해 보겠습니다.
구현
데이터 가져오기
댓글 기능을 구현하기 위해선 우선 현재 댓글의 리스트를 조회해야 합니다. 이러한 상황에서는 주로 useQuery를 사용해 data를 fetching 할 수 있는데요.
다음은 useQuery의 기본 구조입니다.
const fetching = useQuery(query key, query function, query option);
query key는 추후 리스트에 업데이트가 일어났을 때 업데이트된 리스트를 조회하기 위해 사용됩니다.
query function는 key에 의해 Query가 호출이 되면 실행되는 function입니다.
이러한 useQuery의 구조에 따라 다음과 같이 fetching query를 생성할 수 있습니다.
const fetching = async () => {
try {
await axios.get("BASE_URL/comment");
} catch (e: any) {
//error exception handling
}
};
const commentsQuery = useQuery({
queryKey: "comment",
queryFn: fetching,
});
데이터 업데이트
댓글의 리스트를 조회했다면 이제 리스트에 변경사항을 적용할 시간입니다. 데이터의 조회에서는 useQuery를 사용했지만 데이터의 변경에서는 useMutation을 사용합니다.
다음은 useMutation의 기본 구조입니다.
const requestData = useMutation(API Method, Callback);
API Method는 데이터를 변경해주는 Method(Create, Delete, Update)입니다.
CallBack은 onSuccess, onErrored, onSettled를 통해 요청 후 로직을 작성합니다.
onMutate: mutation 함수가 실행되기 전에 실행
onSuccess: 요청이 성공 시 실행
onErrored: 요청이 실패 시 실행
onSettled: 요청의 실패, 성공여부의 관계없이 실행
그리고 로직 안에서 useQuery의 Key를 통해 query를 무효화시키고 새로운 데이터를 fetching 하도록 합니다.
이러한 useMutation의 구조에 따라 다음과 같이 데이터를 업데이트할 수 있습니다.
<Button onClick={() => addComment()}></Button>
const onAddComment = async () => {
return await //댓글추가 API
};
// mutation
const queryClient = useQueryClient();
const { mutate: addComment } = useMutation(onAddComment, {
onMutate: async(newCommentData) => {
// 연산에 영향을 줄 가능성이 있는 쿼리를 정지
await queryClient.cancleQueries("comment");
// 장애 발생 시 롤백
const previousData = queryClient.getQueryData("comment");
// 새로운 data로 캐시 업데이트
queryClient.setQueryData("comment", newCommentData);
// snapshot 값 반환
return {
previousData
}
},
onErrored: (error, context) => {
// 저장한 값으로 롤백
if (context.previousData) {
queryClient.setQueryData("comment", context.previousData);
}
},
onSuccess: (newCommentData) => {
//do something
}
onSettled: () => {
// 성공하거나 실패시 쿼리를 무효화해 최신 데이터를 받아옴
queryClient.invalidateQueries("comment");
},
});
버튼을 클릭하면 mutate method(addComment())의 호출에 의해 useMutation이 실행됩니다. 따라서 onAddComment를 통해 댓글이 추가되고 바로 업데이트가 적용된 리스트를 불러옵니다. 수정이나 삭제를 구현할 때에도 지금 구조에서 API Method만 수정해준다면 손쉽게 기능을 구현할 수 있습니다.

위의 코드는 이해를 돕기 위한 아주 간단한 예제이며, 더 많은 정보는 공식문서를 확인하세요
https://tanstack.com/query/v3/docs/react/guides/optimistic-updates
'Web Frontend > Library' 카테고리의 다른 글
Axios interceptor에서 multiple requests 방지하기 (0) | 2024.06.09 |
---|---|
조금 늦은 Tailwind CSS 사용 후기 (2) | 2024.04.08 |
React-hook-form에서 Cannot read properties of undefined 해결하기 (0) | 2023.06.01 |
Optimistic UI란
우선 시작하기에 앞서 Optimistic UI의 개념에 대해 짚고 넘어가겠습니다
Optimistic UI는 서버의 응답을 기다리지 않고 즉시 UI적인 반응을 보이는 것입니다. 쉽게 말해서 서버에 응답이 이미 성공했을 것이라고 가정하고 UI를 그리는 방식을 일컫는 말이라는 것입니다.
어떤 요청이 높은 확률로 성공한다는 보장이 있을 때, 그 요청이 늦지 않은 시간 안에 응답이 온다는 보장이 있을 때 사용할 수 있는 UI라고 생각하시면 됩니다.
이러한 Optimistic UI를 이용하여 댓글 기능을 구현해 보겠습니다.
구현
데이터 가져오기
댓글 기능을 구현하기 위해선 우선 현재 댓글의 리스트를 조회해야 합니다. 이러한 상황에서는 주로 useQuery를 사용해 data를 fetching 할 수 있는데요.
다음은 useQuery의 기본 구조입니다.
const fetching = useQuery(query key, query function, query option);
query key는 추후 리스트에 업데이트가 일어났을 때 업데이트된 리스트를 조회하기 위해 사용됩니다.
query function는 key에 의해 Query가 호출이 되면 실행되는 function입니다.
이러한 useQuery의 구조에 따라 다음과 같이 fetching query를 생성할 수 있습니다.
const fetching = async () => {
try {
await axios.get("BASE_URL/comment");
} catch (e: any) {
//error exception handling
}
};
const commentsQuery = useQuery({
queryKey: "comment",
queryFn: fetching,
});
데이터 업데이트
댓글의 리스트를 조회했다면 이제 리스트에 변경사항을 적용할 시간입니다. 데이터의 조회에서는 useQuery를 사용했지만 데이터의 변경에서는 useMutation을 사용합니다.
다음은 useMutation의 기본 구조입니다.
const requestData = useMutation(API Method, Callback);
API Method는 데이터를 변경해주는 Method(Create, Delete, Update)입니다.
CallBack은 onSuccess, onErrored, onSettled를 통해 요청 후 로직을 작성합니다.
onMutate: mutation 함수가 실행되기 전에 실행
onSuccess: 요청이 성공 시 실행
onErrored: 요청이 실패 시 실행
onSettled: 요청의 실패, 성공여부의 관계없이 실행
그리고 로직 안에서 useQuery의 Key를 통해 query를 무효화시키고 새로운 데이터를 fetching 하도록 합니다.
이러한 useMutation의 구조에 따라 다음과 같이 데이터를 업데이트할 수 있습니다.
<Button onClick={() => addComment()}></Button>
const onAddComment = async () => {
return await //댓글추가 API
};
// mutation
const queryClient = useQueryClient();
const { mutate: addComment } = useMutation(onAddComment, {
onMutate: async(newCommentData) => {
// 연산에 영향을 줄 가능성이 있는 쿼리를 정지
await queryClient.cancleQueries("comment");
// 장애 발생 시 롤백
const previousData = queryClient.getQueryData("comment");
// 새로운 data로 캐시 업데이트
queryClient.setQueryData("comment", newCommentData);
// snapshot 값 반환
return {
previousData
}
},
onErrored: (error, context) => {
// 저장한 값으로 롤백
if (context.previousData) {
queryClient.setQueryData("comment", context.previousData);
}
},
onSuccess: (newCommentData) => {
//do something
}
onSettled: () => {
// 성공하거나 실패시 쿼리를 무효화해 최신 데이터를 받아옴
queryClient.invalidateQueries("comment");
},
});
버튼을 클릭하면 mutate method(addComment())의 호출에 의해 useMutation이 실행됩니다. 따라서 onAddComment를 통해 댓글이 추가되고 바로 업데이트가 적용된 리스트를 불러옵니다. 수정이나 삭제를 구현할 때에도 지금 구조에서 API Method만 수정해준다면 손쉽게 기능을 구현할 수 있습니다.

위의 코드는 이해를 돕기 위한 아주 간단한 예제이며, 더 많은 정보는 공식문서를 확인하세요
https://tanstack.com/query/v3/docs/react/guides/optimistic-updates
'Web Frontend > Library' 카테고리의 다른 글
Axios interceptor에서 multiple requests 방지하기 (0) | 2024.06.09 |
---|---|
조금 늦은 Tailwind CSS 사용 후기 (2) | 2024.04.08 |
React-hook-form에서 Cannot read properties of undefined 해결하기 (0) | 2023.06.01 |