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."
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>
Ini adalah titik permulaan yang bagus, tetapi bagaimana jika kita menyasarkan responsif peringkat Netflix? Jom tingkatkan teknik kita.
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>
Sekarang, semasa pengguna menuding pada filem, butirannya telah dimuatkan—akses segera selepas mengklik! ✨
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>
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>
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>
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>
<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>
<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>
<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>
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!