※ 해당 섹션은 3버전 react query로 4버전과 다른 부분이 있을 수 있습니다.
ex) [”Comments”, post.id]
currenPage
state...
const maxPostPage = 10;
async function fetchPosts(pageNum) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?_limit=10&_page=${pageNum}`// 각 페이지에 맞는 값을 넣기 위해 pageNum 변수를 넣어준다.
);
return response.json();
}
...
const [currentPage, setCurrentPage] = useState(1); // 최초의 페이지를 1로 정한다.
...
const { data, isError, error, isLoading } = useQuery(
["posts", currentPage], // 현재 페이지에 맞는 currentPage를 의존성 배열로 사용하여 useQuery를 사용하며 구조분해할당을 진행한다.
() => fetchPosts(currentPage), // 익명 함수를 사용하여 currentPage의 fetchPosts를 받는다.
{
staleTime: 2000, // 만료시간 2초
}
);
...
<button
disabled={currentPage <= 1} // 현재 페이지가 1보다 작거나 같으면 비활성화
onClick={() => {
setCurrentPage((previousValue) => previousValue - 1);
}} // 페이지가 1보다 작아지게 onClick event를 활성화한다.
>
Previous page
</button>
<span>Page {currentPage}</span> // 현재 페이지를 나타낸다.
<button
disabled={currentPage >= maxPostPage} // 현재 페이지가 maxPostPage 보다 크거나 같으면 비활성화
onClick={() => {
setCurrentPage((previousValue) => previousValue + 1);
}} // 페이지가 1보다 커지게 onClick event를 활성화한다.
>
Next page
</button>
위처럼 페이지네이션을 진행하고 버튼을 누르면 데이터를 받아오기전에 loading 화면이 나타나게 된다.
이 부분을 방지하기 위해 Prefetching을 진행한다.
리액트 쿼리를 실행하기 위해 useQueryClient
를 불러온다.
import { useQuery, useQueryClient } from "react-query";
...
const queryClient = useQueryClient();
useEffect(() => {
if (currentPage < maxPostPage) { // 현재 페이지가 전체 페이지보단 적을 때
const nextPage = currentPage + 1; // 다음 페이지는 현재 페이지 + 1 이고
queryClient.prefetchQuery(["posts", nextPage], () => // 프리패치를 하기 위해 queryClient.prefetchquery를 기입 후 의존성 배열에 nextPage 기입
fetchPosts(nextPage) // fetchPosts(nextPage)로 기입하여 다음의 데이터를 프리패칭한다.
);
}
}, [currentPage, queryClient]); // useEffect의 의존성 배열은 currentPage 와 queryClient
const { data, isError, error, isLoading } = useQuery(
["posts", currentPage],
() => fetchPosts(currentPage),
{
staleTime: 2000,
keepPreviousData: true,
}
);
...
mutate
functionisLoading
but no isFetching
import { useQuery, useMutation } from "react-query"; // useMutation 선언
...
async function deletePost(postId) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/postId/${postId}`,
{ method: "DELETE" }
);
return response.json();
}
...
const deleteMutation = useMutation((postId) => deletePost(postId)); // useMutation에 deletePost 함수를 넣으나 useQuery와 달리 쿼리키가 없음
...
<button onClick={() => deleteMutation.mutate(post.id)}> // post.id가 deleteMutation.mutate에 각각의 값을 삭제할 수 있도록 설정
Delete</button>
...
{deleteMutation.isError && (
<p style={{ color: "red" }}>Error deleting the post</p>
)} // deleteMutation에 에러가 발생되면 빨간색으로 <p>문구를 보여준다.
{deleteMutation.isLoading && (
<p style={{ color: "purple" }}>Deleting the post</p>
)} // deleteMutation가 로딩중이면 보라색으로 <p>문구를 보여준다.
{deleteMutation.isSuccess && (
<p style={{ color: "green" }}>Post has (not) been deleted</p>
)} // deleteMutation가 완료되면 초록색으로 <p>문구를 보여준다.
...
delete와 같이 update도 거의 동일하게 진행하면 된다.
...
const deleteMutation = useMutation((postId) => deletePost(postId));
const updateMutation = useMutation((postId) => updatePost(postId));
...
<button onClick={() => updateMutation.mutate(post.id)}>
Update title
</button>
...
{updateMutation.isError && (
<p style={{ color: "red" }}>Error updating the post</p>
)}
{updateMutation.isLoading && (
<p style={{ color: "purple" }}>Updating the post</p>
)}
{updateMutation.isSuccess && (
<p style={{ color: "green" }}>Post has (not) been updated</p>
)}
...
useQuery
for dataisLoading / isFetching
and error
staleTime
for whether or not to re-fetch (on trigger) (윈도우가 다시 포커스될 때 같은 특정 트리거에서 쿼리 데이터를 다시 가져올지를 결정한다. 다르게 말하면 staleTime 데이터가 사용가능한 상태로 유지되는 시간입니다. 서버로 돌아가 데이터가 여전히 정확한지 확인해야하는 시점까지요.)cahceTime
for how long to hold on to data after inactivity (데이터가 비활성화된 이후 남아있는 시간을 말합니다. 캐시된 데이터는 쿼리를 다시 실행했을 때 사용되죠. 데이터가 최신 상태인지 서버에서 확인하는 동안 자리표시자로 사용자에게 보여지게 됩니다.)useMutation
for server side-effectsreference
https://www.udemy.com/course/learn-react-query/
https://tanstack.com/query/v4/docs/guides/mutations
https://tanstack.com/query/v4/docs/reference/useMutation
The roofing team I hired showcased an exceptional level of expertise. Their knowledge about various roofing materials and techniques was evident from our initial consultation. They guided me through the selection process https://www.theroofstore.net/
I'm grateful for the unique lens through which you presented your drift hunters ideas in your article. It made for a memorable read
Today I learned (TIL) about the relationship between pagination, pre-fetching, and mutations in modern web development, especially when it comes to performance optimization. Pagination helps in dividing large datasets into smaller, manageable chunks for easier navigation, while pre-fetching anticipates user needs by loading future pages or content in advance, improving the user experience. Mutations, on the other hand, refer to real-time updates that modify data in response to user actions. Understanding how these techniques work together can greatly enhance user interaction, even for niche industries like the roof repair business, where presenting accurate, updated data quickly is essential for engaging potential customers
If the comments section were to constantly refresh in real-time for all users, it would generate a large number of frequent slither io requests to the server, which could lead to performance issues, increased server costs, and potential server crashes during high traffic periods.