Rumah > hujung hadapan web > tutorial js > Membawa React-TanStack-Query ke Tahap Seterusnya dalam Next.js

Membawa React-TanStack-Query ke Tahap Seterusnya dalam Next.js

Linda Hamilton
Lepaskan: 2025-01-22 20:40:10
asal
507 orang telah melayarinya

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

Ingat perbincangan kami sebelum ini tentang menggantikan pendekatan fetch useState useEffect tradisional dengan React-TanStack-Query? Jika anda telah menggunakan asas—menyediakan QueryProvider, menulis pertanyaan asas dan mengendalikan mutasi—anda mungkin sudah mengalami kelebihannya. Walau bagaimanapun, kami baru sahaja mula menerokai keupayaannya.

Mari kita mendalami teknik lanjutan yang akan meningkatkan pengambilan data anda dengan ketara, mengubah prestasi aplikasi anda daripada "baik" kepada "sangat pantas."

Membina Asas yang Lebih Kukuh

Panduan kami sebelum ini menunjukkan penyenaraian filem asas menggunakan React-TanStack-Query:

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

Ini adalah titik permulaan yang bagus, tetapi bagaimana jika kita menyasarkan responsif peringkat Netflix? Jom tingkatkan teknik kita.

Teknik Lanjutan untuk Prestasi Unggul

1. Prefetching Pintar (Mencapai Kelajuan seperti Netflix)

Senarai filem awal kami memerlukan pengguna menunggu selepas mengklik. Kami boleh menambah baik ini secara drastik:

<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>
Salin selepas log masuk
Salin selepas log masuk

Sekarang, semasa pengguna menuding pada filem, butirannya telah dimuatkan—akses segera selepas mengklik! ✨

2. Mempertingkatkan Mutasi (Ingat?)

Artikel awal kami merangkumi mutasi asas. Mari mengoptimumkannya dengan kemas kini optimistik:

<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>
Salin selepas log masuk
Salin selepas log masuk

3. Pemuatan Data Selari (Hapuskan Penantian Yang Tidak Perlu)

Pemuatan berurutan adalah perkara yang sudah berlalu:

<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>
Salin selepas log masuk
Salin selepas log masuk

4. Melaksanakan Penatalan Infinite (Cara yang Cekap)

Mari tingkatkan contoh penomboran kami kepada penatalan tak terhingga yang lancar:

<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>
Salin selepas log masuk

5. Memanfaatkan Komponen Pelayan Next.js 14

Ini ialah ciri yang tidak tersedia dalam artikel pertama kami: Penyepaduan komponen pelayan Next.js 14:

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

Petua Pro (Pengajaran)

  1. Kunci Pertanyaan Konsisten: Perhalusi kunci pertanyaan filem kami:
<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>
Salin selepas log masuk
Salin selepas log masuk
  1. Pengambilan Semula Pintar: Tingkatkan pengambilan semula asas kami pada fokus tetingkap:
<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>
Salin selepas log masuk
Salin selepas log masuk
  1. Pengendalian Ralat Teguh: Tingkatkan pengendalian ralat asas kami:
<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>
Salin selepas log masuk
Salin selepas log masuk

Memilih Teknik Yang Betul

  • Pertanyaan Asas (daripada artikel pertama kami): Sesuai untuk pengambilan data ringkas.
  • Prafetching: Terbaik apabila tindakan pengguna boleh diramalkan.
  • Pertanyaan Selari: Gunakan apabila berbilang set data bebas diperlukan.
  • Pertanyaan Infinite: Sesuai untuk senarai yang panjang dan boleh ditatal.
  • Kemas Kini Optimis: Gunakan untuk pengalaman pengguna serta-merta itu.

Kesimpulan

Kami telah meningkat dengan ketara daripada persediaan awal kami! Penambahbaikan ini penting untuk mencipta pengalaman pengguna yang benar-benar luar biasa.

Ingat, anda tidak perlu melaksanakan semuanya sekaligus. Mulakan dengan asas, kemudian secara beransur-ansur menggabungkan pengoptimuman ini mengikut keperluan.

Apabila seseorang mengulas tentang kelajuan aplikasi anda, anda akan tahu dengan tepat mengapa ia sangat mengagumkan. ?

Selamat pengekodan! React-TanStack-Query menawarkan kemungkinan yang tidak berkesudahan. Apakah yang perlu kita terokai seterusnya?

Atas ialah kandungan terperinci Membawa React-TanStack-Query ke Tahap Seterusnya dalam Next.js. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan