>웹 프론트엔드 >JS 튜토리얼 >Next.js에서 React-TanStack-Query를 한 단계 더 발전시키세요

Next.js에서 React-TanStack-Query를 한 단계 더 발전시키세요

Linda Hamilton
Linda Hamilton원래의
2025-01-22 20:40:10551검색

Taking React-TanStack-Query to the Next Level in Next.js

기존 fetch useState useEffect 접근 방식을 React-TanStack-Query로 바꾸는 것에 대한 이전 논의를 기억하시나요? QueryProvider 설정, 기본 쿼리 작성, 변형 처리 등 기본 사항을 사용해 왔다면 이미 이점을 경험했을 것입니다. 그러나 우리는 이제 막 그 기능을 탐색하기 시작했습니다.

데이터 가져오기를 크게 향상시켜 애플리케이션 성능을 "좋음"에서 "매우 빠른" 수준으로 변화시키는 고급 기술을 자세히 살펴보겠습니다.

더 강력한 기반 구축

이전 가이드에서는 React-TanStack-Query를 사용한 기본 영화 목록을 보여주었습니다.

<code class="language-javascript">const { data: movies, error, isLoading } = useQuery(['movies'], fetchMovies);</code>

이것은 좋은 출발점이지만 넷플릭스 수준의 반응성을 목표로 한다면 어떨까요? 기술을 한층 더 끌어올리자.

우수한 성능을 위한 첨단 기술

1. 지능형 프리페칭(Netflix 수준의 속도 구현)

초기 영화 목록에서는 사용자가 클릭한 후 기다려야 했습니다. 이를 대폭 개선할 수 있습니다.

<code class="language-javascript">// components/MovieList.jsx
import { useQueryClient } from '@tanstack/react-query';

export default function MovieList() {
  const queryClient = useQueryClient();

  // Leveraging our existing fetchMovies function
  const prefetchMovie = async (movieId) => {
    await queryClient.prefetchQuery({
      queryKey: ['movie', movieId],
      queryFn: () => fetchMovieDetails(movieId),
      // Maintain freshness for 5 minutes
      staleTime: 5 * 60 * 1000,
    });
  };

  return (
    <div className="grid grid-cols-4 gap-4">
      {movies.map(movie => (
        <div key={movie.id} onMouseEnter={() => prefetchMovie(movie.id)}
          className="movie-card"
        >
          {movie.title}
        </div>
      ))}
    </div>
  );
}</code>

이제 사용자가 영화 위로 마우스를 가져가면 세부정보가 미리 로드되어 클릭 시 즉시 액세스할 수 있습니다! ✨

2. 돌연변이 강화(기억하시나요?)

초기 기사에서는 기본 돌연변이를 다루었습니다. 낙관적인 업데이트로 최적화해 보겠습니다.

<code class="language-javascript">// hooks/useUpdateMovie.js
export function useUpdateMovie() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: updateMovie,
    // The key improvement
    onMutate: async (newMovie) => {
      // Halt ongoing refetches
      await queryClient.cancelQueries(['movie', newMovie.id]);

      // Store current state (for rollback if needed)
      const previousMovie = queryClient.getQueryData(['movie', newMovie.id]);

      // Immediate (optimistic) update
      queryClient.setQueryData(['movie', newMovie.id], newMovie);

      return { previousMovie };
    },
    // Error handling
    onError: (err, newMovie, context) => {
      queryClient.setQueryData(
        ['movie', newMovie.id],
        context.previousMovie
      );
    },
  });
}</code>

3. 병렬 데이터 로딩(불필요한 대기 제거)

순차 로딩은 이제 과거의 일입니다.

<code class="language-javascript">// pages/movie/[id].js
export default function MoviePage({ movieId }) {
  const results = useQueries({
    queries: [
      {
        queryKey: ['movie', movieId],
        queryFn: () => fetchMovie(movieId),
      },
      {
        queryKey: ['cast', movieId],
        queryFn: () => fetchCast(movieId),
      },
      {
        queryKey: ['reviews', movieId],
        queryFn: () => fetchReviews(movieId),
      },
    ],
  });

  if (results.some(result => result.isLoading)) {
    return <LoadingSpinner />;
  }

  const [movie, cast, reviews] = results.map(r => r.data);

  return <MovieDetails cast={cast} movie={movie} reviews={reviews} />;
}</code>

4. 무한 스크롤 구현(효율적인 방법)

페이지를 매긴 예제를 원활한 무한 스크롤로 업그레이드해 보겠습니다.

<code class="language-javascript">// components/InfiniteMovieList.jsx
import { useInfiniteQuery } from '@tanstack/react-query';
import { useInView } from 'react-intersection-observer';

export default function InfiniteMovieList() {
  const { ref, inView } = useInView();

  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery({
    queryKey: ['movies'],
    queryFn: fetchMoviePage,
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  });

  useEffect(() => {
    if (inView && hasNextPage) {
      fetchNextPage();
    }
  }, [inView, hasNextPage]);

  return (
    <div>
      {data.pages.map((page) => (
        page.movies.map((movie) => (
          <MovieCard key={movie.id} movie={movie} />
        ))
      ))}

      <div ref={ref}>
        {isFetchingNextPage ? <LoadingSpinner /> : null}
      </div>
    </div>
  );
}</code>

5. Next.js 14 서버 구성요소 활용

이것은 첫 번째 기사인 Next.js 14 서버 구성 요소 통합에서 사용할 수 없는 기능입니다.

<code class="language-javascript">const { data: movies, error, isLoading } = useQuery(['movies'], fetchMovies);</code>

전문가의 팁(경험한 교훈)

  1. 일관적인 쿼리 키: 영화 쿼리 키 개선:
<code class="language-javascript">// components/MovieList.jsx
import { useQueryClient } from '@tanstack/react-query';

export default function MovieList() {
  const queryClient = useQueryClient();

  // Leveraging our existing fetchMovies function
  const prefetchMovie = async (movieId) => {
    await queryClient.prefetchQuery({
      queryKey: ['movie', movieId],
      queryFn: () => fetchMovieDetails(movieId),
      // Maintain freshness for 5 minutes
      staleTime: 5 * 60 * 1000,
    });
  };

  return (
    <div className="grid grid-cols-4 gap-4">
      {movies.map(movie => (
        <div key={movie.id} onMouseEnter={() => prefetchMovie(movie.id)}
          className="movie-card"
        >
          {movie.title}
        </div>
      ))}
    </div>
  );
}</code>
  1. 지능형 다시 가져오기: 창 초점에 대한 기본 다시 가져오기 개선:
<code class="language-javascript">// hooks/useUpdateMovie.js
export function useUpdateMovie() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: updateMovie,
    // The key improvement
    onMutate: async (newMovie) => {
      // Halt ongoing refetches
      await queryClient.cancelQueries(['movie', newMovie.id]);

      // Store current state (for rollback if needed)
      const previousMovie = queryClient.getQueryData(['movie', newMovie.id]);

      // Immediate (optimistic) update
      queryClient.setQueryData(['movie', newMovie.id], newMovie);

      return { previousMovie };
    },
    // Error handling
    onError: (err, newMovie, context) => {
      queryClient.setQueryData(
        ['movie', newMovie.id],
        context.previousMovie
      );
    },
  });
}</code>
  1. 강력한 오류 처리: 기본 오류 처리 강화:
<code class="language-javascript">// pages/movie/[id].js
export default function MoviePage({ movieId }) {
  const results = useQueries({
    queries: [
      {
        queryKey: ['movie', movieId],
        queryFn: () => fetchMovie(movieId),
      },
      {
        queryKey: ['cast', movieId],
        queryFn: () => fetchCast(movieId),
      },
      {
        queryKey: ['reviews', movieId],
        queryFn: () => fetchReviews(movieId),
      },
    ],
  });

  if (results.some(result => result.isLoading)) {
    return <LoadingSpinner />;
  }

  const [movie, cast, reviews] = results.map(r => r.data);

  return <MovieDetails cast={cast} movie={movie} reviews={reviews} />;
}</code>

올바른 기술 선택

  • 기본 쿼리(첫 번째 기사에서): 간단한 데이터 가져오기에 이상적입니다.
  • 프리페치: 사용자 작업을 예측할 수 있는 경우에 가장 적합합니다.
  • 병렬 쿼리: 여러 개의 독립적인 데이터 세트가 필요할 때 사용하세요.
  • 무한 쿼리: 길고 스크롤 가능한 목록에 적합합니다.
  • 낙관적 업데이트: 즉각적인 사용자 경험을 위해 사용하세요.

결론

초기 설정보다 훨씬 발전했습니다! 이러한 개선 사항은 정말 뛰어난 사용자 경험을 만드는 데 매우 중요합니다.

모든 것을 한 번에 구현할 필요는 없다는 점을 기억하세요. 기본부터 시작한 다음 필요에 따라 이러한 최적화를 점진적으로 통합하세요.

다음에 누군가가 귀하의 애플리케이션 속도에 대해 언급하면 ​​그것이 왜 그렇게 인상적인지 정확히 알게 될 것입니다. ?

즐거운 코딩하세요! React-TanStack-Query는 무한한 가능성을 제공합니다. 다음에는 무엇을 살펴볼까요?

위 내용은 Next.js에서 React-TanStack-Query를 한 단계 더 발전시키세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.