首頁 >web前端 >js教程 >完整的 redux 工具包(第 4 部分)

完整的 redux 工具包(第 4 部分)

PHPz
PHPz原創
2024-09-11 14:32:39924瀏覽

Complete redux toolkit (Part - 4)

第 4 部分:RTK 查詢中的進階主題

本部分將重點介紹 RTK 查詢中的高階功能和用例,包括自訂查詢、處理身分驗證、樂觀更新和效能最佳化。

第 4 部分:RTK 查詢中的進階主題

1. 進階RTK查詢概念介紹

在上一部分中,我們介紹了使用 RTK 查詢來獲取和更改資料的基礎知識。現在,我們將深入研究更高級的功能,使 RTK 查詢變得更加強大。這些功能可讓您自訂查詢、管理身份驗證、最佳化效能並處理樂觀更新,以獲得更流暢的使用者體驗。

2. 自訂baseQuery進行身份驗證

使用需要驗證的 API 時,您需要自訂 baseQuery 以包含 JWT 令牌或 API 金鑰等驗證標頭。

第 1 步:建立自訂基本查詢

您可以建立一個自訂的 baseQuery 函數,為每個要求新增授權標頭。

// src/app/customBaseQuery.js
import { fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const customBaseQuery = fetchBaseQuery({
  baseUrl: 'https://jsonplaceholder.typicode.com/',
  prepareHeaders: (headers, { getState }) => {
    const token = getState().auth.token; // Assuming auth slice has token
    if (token) {
      headers.set('Authorization', `Bearer ${token}`);
    }
    return headers;
  },
});

export default customBaseQuery;

說明:

  • prepareHeaders:此函數可讓您為每個請求自訂標頭。它從 Redux 儲存中檢索令牌並將其附加到 Authorization 標頭。

步驟2:在createApi中使用自訂baseQuery

修改 postsApi.js 檔案以使用自訂基本查詢:

// src/features/posts/postsApi.js
import { createApi } from '@reduxjs/toolkit/query/react';
import customBaseQuery from '../../app/customBaseQuery';

export const postsApi = createApi({
  reducerPath: 'postsApi',
  baseQuery: customBaseQuery, // Use the custom base query here
  tagTypes: ['Post'],
  endpoints: (builder) => ({
    fetchPosts: builder.query({
      query: () => 'posts',
      providesTags: (result) =>
        result ? result.map(({ id }) => ({ type: 'Post', id })) : ['Post'],
    }),
    addPost: builder.mutation({
      query: (newPost) => ({
        url: 'posts',
        method: 'POST',
        body: newPost,
      }),
      invalidatesTags: ['Post'],
    }),
  }),
});

export const { useFetchPostsQuery, useAddPostMutation } = postsApi;

3. 使用 RTK 查詢進行樂觀更新

樂觀更新可讓您在伺服器確認突變之前立即更新 UI,提供更流暢的使用者體驗。如果伺服器回傳錯誤,UI 可以恢復到先前的狀態。

第 1 步:在突變中實施樂觀更新

您可以使用 RTK Query 提供的 onQueryStarted 生命週期方法來實現樂觀更新。

// src/features/posts/postsApi.js
addPost: builder.mutation({
  query: (newPost) => ({
    url: 'posts',
    method: 'POST',
    body: newPost,
  }),
  invalidatesTags: ['Post'],
  onQueryStarted: async (newPost, { dispatch, queryFulfilled }) => {
    // Optimistic update: immediately add the new post to the cache
    const patchResult = dispatch(
      postsApi.util.updateQueryData('fetchPosts', undefined, (draftPosts) => {
        draftPosts.push({ id: Date.now(), ...newPost }); // Fake ID for optimistic update
      })
    );
    try {
      await queryFulfilled; // Await server response
    } catch {
      patchResult.undo(); // Revert if the mutation fails
    }
  },
}),

說明:

  • onQueryStarted:當突變開始時會觸發此生命週期方法。它提供了dispatch和queryFulfilled參數來管理快取更新。
  • postsApi.util.updateQueryData:這個實用函數允許您樂觀地更新快取資料。
  • patchResult.undo():如果伺服器傳回錯誤,則恢復樂觀更新。

4. 處理相關查詢

有時,您可能需要執行相關查詢,其中一個查詢依賴另一個查詢的結果。 RTK 查詢提供了skip 參數來控制查詢何時執行。

範例:根據所選帖子 ID 獲取帖子詳細信息

// src/features/posts/PostDetails.js
import React from 'react';
import { useFetchPostQuery } from './postsApi';

const PostDetails = ({ postId }) => {
  const { data: post, error, isLoading } = useFetchPostQuery(postId, { skip: !postId });

  if (!postId) return <p>Select a post to view details.</p>;
  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error loading post details.</p>;

  return (
    <div>
      <h3>{post.title}</h3>
      <p>{post.body}</p>
    </div>
  );
};

export default PostDetails;

說明:

  • useFetchPostQuery:以 postId 作為參數的查詢掛鉤。如果未提供 postId,則使用 {skip: !postId } 跳過查詢。

5. 使用 RTK 查詢輪詢和即時數據

RTK 查詢支援輪詢,以指定的時間間隔保持資料最新。這對於即時資料同步很有用。

第 1 步:在查詢中使用輪詢

您可以使用 pollingInterval 選項為任何查詢啟用輪詢。

// src/features/posts/PostsList.js
import React from 'react';
import { useFetchPostsQuery } from './postsApi';

const PostsList = () => {
  const { data: posts, error, isLoading } = useFetchPostsQuery(undefined, {
    pollingInterval: 30000, // Poll every 30 seconds
  });

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>An error occurred: {error.message}</p>;

  return (
    <section>
      <h2>Posts</h2>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </section>
  );
};

export default PostsList;

說明:

  • pollingInterval:此選項指定查詢應輪詢伺服器以取得新資料的時間間隔(以毫秒為單位)。

6. 使用 selectFromResult 優化效能

RTK 查詢提供 selectFromResult 選項以實現進階效能最佳化,讓您可以從查詢結果中選擇特定資料。

步驟 1: 使用 selectFromResult 最佳化重新渲染

當只需要查詢結果的子集時,可以使用 selectFromResult 選項來防止不必要的重新渲染。

// src/features/posts/PostTitleList.js
import React from 'react';
import { useFetchPostsQuery } from './postsApi';

const PostTitleList = () => {
  const { data: posts } = useFetchPostsQuery(undefined, {
    selectFromResult: ({ data }) => ({ titles: data?.map((post) => post.title) }),
  });

  return (
    <section>
      <h2>Post Titles</h2>
      <ul>
        {posts?.map((title, index) => (
          <li key={index}>{title}</li>
        ))}
      </ul>
    </section>
  );
};

export default PostTitleList;

說明:

  • selectFromResult:此選項可讓您僅從取得的貼文中選擇標題,防止查詢結果中的其他資料發生變更時不必要的重新渲染。

7. 結論與後續步驟

在這一部分中,我們探討了 RTK 查詢中的高級主題,例如自訂用於身份驗證的 baseQuery、處理樂觀更新、管理依賴查詢、使用輪詢進行即時資料同步以及使用 selectFromResult 優化效能。 RTK Query 豐富的功能集使其成為現代 Redux 應用程式中處理資料擷取和快取的強大工具。

在下一部分中,我們將討論Redux Toolkit 和 RTK 查詢的測試策略,涵蓋單元測試、整合測試以及確保程式碼健壯和可維護的最佳實踐。

請關注第 5 部分:Redux 工具包和 RTK 查詢的測試策略

以上是完整的 redux 工具包(第 4 部分)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn