首頁 >web前端 >js教程 >透過 RTK 查詢在 React Native 中高效處理數據

透過 RTK 查詢在 React Native 中高效處理數據

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-11-30 10:01:14940瀏覽

在本指南中,我們將介紹:

  • CRUD 操作
  • 分頁
  • Redux 透過 RTK 查詢持久化
  • 多個基本 URL 使用
  • 受保護與公共路線
  • 快取管理與失效

Efficient Data Handling in React Native with RTK Query

RTK 查詢 是內建於 Redux Toolkit (RTK) 中的進階資料擷取與快取工具。它透過為獲取、快取和更新資料等常見任務產生 Redux 切片和掛鉤來簡化 API 互動。主要功能包括:

  1. 自動快取:RTK Query 快取數據,並在數據失效時自動重新獲取,確保 UI 始終擁有最新數據。
  2. 快取失效:RTK 查詢使用標籤,讓您定義何時應重新取得某些資料。這有助於保持快取最新,無需手動更新資料。
  3. 自動產生的鉤子:RTK Query 為每個 API 端點建立鉤子,讓您可以使用簡單的 React 鉤子(useGetPostsQuery、useCreatePostMutation 等)呼叫 API。
  4. 錯誤處理:包括透過中間件的自訂錯誤處理,可以輕鬆捕獲和顯示錯誤。
  5. 簡化的 Redux 整合:RTK Query 直接與 Redux 集成,因此您不需要額外的函式庫來進行全域狀態管理或快取。

RTK 查詢與 React 查詢

React QueryRTK Query 都提供了 React 應用程式中的資料取得和快取解決方案,但它們具有不同的優勢和用例:

Feature RTK Query React Query
Purpose Integrated within Redux for managing server data in Redux state. Best for apps already using Redux or requiring centralized global state. Dedicated to managing server state with no Redux dependency. Great for apps focused on server state without Redux.
Caching Automatic caching with fine-grained cache invalidation through tags. Caches data globally within the Redux store. Automatic caching with flexible cache control policies. Maintains a separate cache independent of Redux.
Generated Hooks Auto-generates hooks for endpoints, allowing mutations and queries using useQuery and useMutation hooks. Provides hooks (useQuery, useMutation) that work independently from Redux, but require manual configuration of queries and mutations.
DevTools Integrated into Redux DevTools, making debugging seamless for Redux users. Provides its own React Query DevTools, with detailed insight into query states and cache.
Error Handling Centralized error handling using Redux middleware. Error handling within individual queries, with some centralized error-handling options.
Redux Integration Built directly into Redux, simplifying usage for Redux-based apps. Not integrated with Redux by default, although Redux and React Query can be combined if needed.

在 RTK 查詢和 React 查詢之間進行選擇:

  • 使用 RTK 查詢如果:

    • 您已經在使用 Redux,並且想要一個整合的、簡化的資料擷取解決方案。
    • 您需要在 Redux 中進行集中式錯誤處理和開發工具整合。
  • 使用 React 查詢 如果:

    • 您想要一個更輕量級的設置,無需 Redux 依賴。
    • 您喜歡單獨的伺服器狀態管理,不需要全域應用程式狀態。

本質上,RTK Query 非常適合以Redux 為中心的應用程序,而React Query 為沒有Redux 的專案或那些注重本地化伺服器狀態管理的專案提供了靈活性和簡單性。


Efficient Data Handling in React Native with RTK Query



1. 商店配置與設定

// src/store/store.js
import AsyncStorage from '@react-native-async-storage/async-storage';
import { combineReducers, configureStore, isRejectedWithValue } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query';
import { FLUSH, PAUSE, PERSIST, persistReducer, PURGE, REGISTER, REHYDRATE } from 'redux-persist';
import { authApi } from '../api/authApi';
import { postsApi } from '../api/postsApi';
import { usersApi } from '../api/usersApi';
import authSlice from '../features/auth/authSlice';

const persistConfig = {
  key: 'root',
  version: 1,
  storage: AsyncStorage,
  blacklist: ['auth', postsApi.middleware, usersApi.middleware, authApi.middleware], // these reduce will not persist data (NOTE: blacklist rtk api slices so that to use tags)
  // whitelist: ['users'], //these reduce will persist data
};

const getEnhancers = (getDefaultEnhancers) => {
  if (process.env.NODE_ENV === 'development') {
    const reactotron = require('../reactotronConfig/ReactotronConfig').default;
    return getDefaultEnhancers().concat(reactotron.createEnhancer());
  }
  return getDefaultEnhancers();
};

/**
 * On api error this will be called
 */
export const rtkQueryErrorLogger = (api) => (next) => (action) => {
  // RTK Query uses `createAsyncThunk` from redux-toolkit under the hood, so we're able to utilize these matchers!
  if (isRejectedWithValue(action)) {
    console.log('isRejectedWithValue', action.error, action.payload);
    alert(JSON.stringify(action)); // This is just an example. You can replace it with your preferred method for displaying notifications.
  }

  return next(action);
};

const reducer = combineReducers({
  auth: authSlice,
  [postsApi.reducerPath]: postsApi.reducer,
  [usersApi.reducerPath]: usersApi.reducer,
  [authApi.reducerPath]: authApi.reducer,
});
const persistedReducer = persistReducer(persistConfig, reducer);

const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }).concat(postsApi.middleware, usersApi.middleware, authApi.middleware, rtkQueryErrorLogger),
  enhancers: getEnhancers,
});

setupListeners(store.dispatch);

export default store;

  • Redux Store (src/store/store.js):Redux store 是保存應用程式狀態的主要結構。在您的設定中,它透過 redux-persist 進行了增強,可以在本地保存 Redux 狀態的某些部分,因此即使應用程式重新啟動,它們也會持續存在。

  • redux-persist:

    • 用途:幫助保持部分 Redux 狀態在應用程式會話中保持不變。
    • 配置:persistConfig 物件指定 auth、postsApi 和 usersApi 不應被持久化(列入黑名單),這表示它們的資料會在應用程式重新啟動時重置。
    • persistReducer 將減速器配置與持久化功能結合。
  • 增強器:自訂增強器用於在開發模式下整合Reactotron,這是一個調試 Redux 操作、狀態和網路請求的有用工具。這只在開發時激活,使調試更容易,而不影響生產。

  • 中介軟體:

    • RTK 查詢中間件(postsApi.middleware、usersApi.middleware、authApi.middleware)新增自動快取管理功能,提升資料擷取效率。
    • rtkQueryErrorLogger:自訂中間件在 API 呼叫失敗時記錄錯誤。它使用 RTK Query 的 isRejectedWithValue 函數來捕獲和處理錯誤,讓您可以提醒使用者有關問題或採取其他操作。
  • setupListeners:此功能可以在發生某些事件時自動重新獲取數據,例如當應用程式重新獲得焦點或從後台恢復時,為用戶提供新鮮數據,而無需手動重新整理.



2. RTK 查詢的 API 定義

RTK Query 透過自動產生 Redux 切片、掛鉤和快取來簡化 API 呼叫。以下是您定義的 API 的詳細資訊:

// src/store/store.js
import AsyncStorage from '@react-native-async-storage/async-storage';
import { combineReducers, configureStore, isRejectedWithValue } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query';
import { FLUSH, PAUSE, PERSIST, persistReducer, PURGE, REGISTER, REHYDRATE } from 'redux-persist';
import { authApi } from '../api/authApi';
import { postsApi } from '../api/postsApi';
import { usersApi } from '../api/usersApi';
import authSlice from '../features/auth/authSlice';

const persistConfig = {
  key: 'root',
  version: 1,
  storage: AsyncStorage,
  blacklist: ['auth', postsApi.middleware, usersApi.middleware, authApi.middleware], // these reduce will not persist data (NOTE: blacklist rtk api slices so that to use tags)
  // whitelist: ['users'], //these reduce will persist data
};

const getEnhancers = (getDefaultEnhancers) => {
  if (process.env.NODE_ENV === 'development') {
    const reactotron = require('../reactotronConfig/ReactotronConfig').default;
    return getDefaultEnhancers().concat(reactotron.createEnhancer());
  }
  return getDefaultEnhancers();
};

/**
 * On api error this will be called
 */
export const rtkQueryErrorLogger = (api) => (next) => (action) => {
  // RTK Query uses `createAsyncThunk` from redux-toolkit under the hood, so we're able to utilize these matchers!
  if (isRejectedWithValue(action)) {
    console.log('isRejectedWithValue', action.error, action.payload);
    alert(JSON.stringify(action)); // This is just an example. You can replace it with your preferred method for displaying notifications.
  }

  return next(action);
};

const reducer = combineReducers({
  auth: authSlice,
  [postsApi.reducerPath]: postsApi.reducer,
  [usersApi.reducerPath]: usersApi.reducer,
  [authApi.reducerPath]: authApi.reducer,
});
const persistedReducer = persistReducer(persistConfig, reducer);

const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }).concat(postsApi.middleware, usersApi.middleware, authApi.middleware, rtkQueryErrorLogger),
  enhancers: getEnhancers,
});

setupListeners(store.dispatch);

export default store;

  • authApi (src/api/authApi.js):
    • 定義登入突變,將使用者憑證(例如使用者名稱、密碼)傳送到伺服器進行身份驗證。
    • onQueryStarted:登入成功後,它使用 setToken 操作將傳回的令牌儲存在 Redux 中。這可以實現對其他端點的安全性、經過身份驗證的請求。

// src/api/authApi.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { setToken } from '../features/auth/authSlice';

export const authApi = createApi({
  reducerPath: 'authApi',
  baseQuery: fetchBaseQuery({
    baseUrl: 'https://dummyjson.com/auth/',
  }),
  endpoints: (builder) => ({
    login: builder.mutation({
      query: (credentials) => ({
        url: 'login',
        method: 'POST',
        body: credentials,
      }),
      async onQueryStarted(arg, { dispatch, queryFulfilled }) {
        try {
          const { data } = await queryFulfilled;
          dispatch(setToken(data.accessToken)); // Store the token in Redux
        } catch (error) {
          console.error('Login error:', error);
        }
      },
    }),
  }),
});

export const { useLoginMutation } = authApi;
  • postsApi (src/api/postsApi.js):
    • CRUD 操作:貼文 API 包含多個與貼文互動的端點(取得、建立、更新、刪除)。
      • getPosts:獲取分頁帖子,這意味著它以較小的區塊(頁面)檢索數據,從而提高效能和載入時間。
      • createPost、updatePost 和 deletePost:其中每一個都執行不同的操作(建立、更新或刪除貼文)。
    • 用於快取的標籤:每個端點都使用標籤(例如,{ type: 'Posts', id })自動管理快取失效和刷新。例如,建立或刪除貼文會使快取失效,從而提示 getPosts 無需手動幹預即可取得新資料。

// src/store/store.js
import AsyncStorage from '@react-native-async-storage/async-storage';
import { combineReducers, configureStore, isRejectedWithValue } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query';
import { FLUSH, PAUSE, PERSIST, persistReducer, PURGE, REGISTER, REHYDRATE } from 'redux-persist';
import { authApi } from '../api/authApi';
import { postsApi } from '../api/postsApi';
import { usersApi } from '../api/usersApi';
import authSlice from '../features/auth/authSlice';

const persistConfig = {
  key: 'root',
  version: 1,
  storage: AsyncStorage,
  blacklist: ['auth', postsApi.middleware, usersApi.middleware, authApi.middleware], // these reduce will not persist data (NOTE: blacklist rtk api slices so that to use tags)
  // whitelist: ['users'], //these reduce will persist data
};

const getEnhancers = (getDefaultEnhancers) => {
  if (process.env.NODE_ENV === 'development') {
    const reactotron = require('../reactotronConfig/ReactotronConfig').default;
    return getDefaultEnhancers().concat(reactotron.createEnhancer());
  }
  return getDefaultEnhancers();
};

/**
 * On api error this will be called
 */
export const rtkQueryErrorLogger = (api) => (next) => (action) => {
  // RTK Query uses `createAsyncThunk` from redux-toolkit under the hood, so we're able to utilize these matchers!
  if (isRejectedWithValue(action)) {
    console.log('isRejectedWithValue', action.error, action.payload);
    alert(JSON.stringify(action)); // This is just an example. You can replace it with your preferred method for displaying notifications.
  }

  return next(action);
};

const reducer = combineReducers({
  auth: authSlice,
  [postsApi.reducerPath]: postsApi.reducer,
  [usersApi.reducerPath]: usersApi.reducer,
  [authApi.reducerPath]: authApi.reducer,
});
const persistedReducer = persistReducer(persistConfig, reducer);

const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }).concat(postsApi.middleware, usersApi.middleware, authApi.middleware, rtkQueryErrorLogger),
  enhancers: getEnhancers,
});

setupListeners(store.dispatch);

export default store;

  • usersApi (src/api/usersApi.js):
    • 此 API 取得經過驗證的使用者的個人資料,根據 Redux 中的令牌設定授權標頭。
    • Headers:prepareHeaders 動態地將令牌附加到每個請求(如果可用),從而允許安全且授權的 API 請求。


3. Auth Slice (src/features/auth/authSlice.js)

// src/api/authApi.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { setToken } from '../features/auth/authSlice';

export const authApi = createApi({
  reducerPath: 'authApi',
  baseQuery: fetchBaseQuery({
    baseUrl: 'https://dummyjson.com/auth/',
  }),
  endpoints: (builder) => ({
    login: builder.mutation({
      query: (credentials) => ({
        url: 'login',
        method: 'POST',
        body: credentials,
      }),
      async onQueryStarted(arg, { dispatch, queryFulfilled }) {
        try {
          const { data } = await queryFulfilled;
          dispatch(setToken(data.accessToken)); // Store the token in Redux
        } catch (error) {
          console.error('Login error:', error);
        }
      },
    }),
  }),
});

export const { useLoginMutation } = authApi;
  • authSlice:Redux 切片管理特定的狀態,在本例中為使用者驗證。
  • 狀態管理:authSlice 保留使用者的令牌,用於存取受保護的 API 端點。
  • 行動
    • setToken:在 Redux 狀態中儲存身份驗證令牌。
    • logout:從 Redux 中清除令牌,有效地將使用者登出。


4. 用於調試的Reactotron (src/reactotronConfig/ReactotronConfig.js)

// src/api/postsApi.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

// Define the postsApi slice with RTK Query
export const postsApi = createApi({
  // Unique key for the API slice in Redux state
  reducerPath: 'postsApi',

  // Configure base query settings, including the base URL for all requests
  baseQuery: fetchBaseQuery({
    baseUrl: 'https://jsonplaceholder.typicode.com',
  }),

  // Define cache tag types for automatic cache invalidation
  tagTypes: ['Posts'],

  // Define API endpoints (queries and mutations)
  endpoints: (builder) => ({
    // Query to fetch a paginated list of posts
    getPosts: builder.query({
      // URL and parameters for paginated posts
      query: ({ page = 1, limit = 10 }) => `/posts?_page=${page}&_limit=${limit}`,

      // Tagging posts to automatically refresh this cache when needed
      providesTags: (result) =>
        result
          ? [...result.map(({ id }) => ({ type: 'Posts', id })), { type: 'Posts', id: 'LIST' }]
          : [{ type: 'Posts', id: 'LIST' }],
    }),

    // Query to fetch a single post by its ID
    getPostById: builder.query({
      // Define query with post ID in the URL path
      query: (id) => `/posts/${id}`,

      // Tag individual post by ID for selective cache invalidation
      providesTags: (result, error, id) => [{ type: 'Posts', id }],
    }),

    // Mutation to create a new post
    createPost: builder.mutation({
      // Configure the POST request details and payload
      query: (newPost) => ({
        url: '/posts',
        method: 'POST',
        body: newPost,
      }),

      // Invalidate all posts (paginated list) to refresh after creating a post
      invalidatesTags: [{ type: 'Posts', id: 'LIST' }],
    }),

    // Mutation to update an existing post by its ID
    updatePost: builder.mutation({
      // Define the PUT request with post ID and updated data in the payload
      query: ({ id, ...updatedData }) => ({
        url: `/posts/${id}`,
        method: 'PUT',
        body: updatedData,
      }),

      // Invalidate cache for both the updated post and the paginated list
      invalidatesTags: (result, error, { id }) => [
        { type: 'Posts', id },
        { type: 'Posts', id: 'LIST' },
      ],
    }),

    // Mutation to delete a post by its ID
    deletePost: builder.mutation({
      // Define the DELETE request with post ID in the URL path
      query: (id) => ({
        url: `/posts/${id}`,
        method: 'DELETE',
      }),

      // Invalidate cache for the deleted post and the paginated list
      invalidatesTags: (result, error, id) => [
        { type: 'Posts', id },
        { type: 'Posts', id: 'LIST' },
      ],
    }),
  }),
});

// Export generated hooks for each endpoint to use them in components
export const {
  useGetPostsQuery, // Use this when you want data to be fetched automatically as the component mounts or when the query parameters change.
  useLazyGetPostsQuery, // Use this when you need more control over when the query runs, such as in response to a user action (e.g., clicking a button), conditional fetching, or specific events.
  useGetPostByIdQuery,
  useCreatePostMutation,
  useUpdatePostMutation,
  useDeletePostMutation,
} = postsApi;
  • Reactotron:Reactotron 是一個偵錯工具,有助於追蹤 Redux 狀態變更、監控 API 請求和檢查日誌。
  • Setup:配置為捕獲 console.log 輸出和 Redux 操作。在開發模式下,此設定提供了一種強大的調試方法,無需添加額外的程式碼或改變生產效能。


5. 主要應用元件

// src/api/usersApi.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const usersApi = createApi({
  reducerPath: 'usersApi',
  baseQuery: fetchBaseQuery({
    baseUrl: 'https://dummyjson.com',
    prepareHeaders: (headers, { getState }) => {
      // Get the token from the Redux auth state
      const { token } = getState().auth;

      // If the token exists, set it in the Authorization header
      if (token) {
        headers.set('Authorization', `Bearer ${token}`);
      }

      // Optional: include credentials if needed by the API
      headers.set('credentials', 'include');

      return headers;
    },
  }),
  endpoints: (builder) => ({
    // Fetch user profile with token in Authorization header
    getUserProfile: builder.query({
      query: () => '/auth/me',
    }),
  }),
});

export const { useGetUserProfileQuery } = usersApi;
  • 應用程式元件(src/App.js)
    • App 元件將整個應用程式包裝在 Provider(以使 Redux 可用)和 PersistGate(延遲渲染,直到檢索到持久狀態)。
    • PersistGate 確保在應用程式顯示之前持久載入數據,減少載入時間不一致。

// src/MainApp.js
從 'react' 導入 React, { useEffect, useState };
進口 {
  活動指示器,
  按鈕,
  平面列表,
  莫代爾,
  刷新控制,
  樣式表,
  文字,
  文字輸入,
  看法,
來自 'react-native';
從 'react-native-safe-area-context' 導入 { SafeAreaView } ;
從 'react-redux' 導入 { useDispatch, useSelector };
從 './api/authApi' 導入 { useLoginMutation } ;
進口 {
  使用CreatePostMutation,
  使用DeletePostMutation,
  使用GetPosts查詢,
  使用LazyGetPosts查詢,
  使用更新後突變,
來自 './api/postsApi';
從'./api/usersApi'導入{useGetUserProfileQuery};
導入{註銷}來自“./features/auth/authSlice”;

const MainApp = () =>; {
  const [newPostTitle, setNewPostTitle] = useState('');
  const [頁面,setPage] = useState(1);
  const [postsData, setPostsData] = useState([]);
  const [刷新,setRefreshing] = useState(false);
  const [isModalVisible, setModalVisible] = useState(false);

  const 調度 = useDispatch();
  const token = useSelector((state) => state.auth.token);

  // 登入突變
  const [login, { isLoading: isLoggingIn }] = useLoginMutation();

  // 當令牌可用時取得使用者設定檔
  const { 資料:userProfile,重新取得:refetchUserProfile } = useGetUserProfileQuery(未定義,{
    跳過:!令牌,
  });

  // 取得分頁帖子
  常量{
    數據:帖子,
    正在加載,
    正在獲取,
    是錯誤,
    重新獲取,
  } = useGetPostsQuery({ 頁數, 限制: 10 }); // 當你想在螢幕載入時取得資料時,使用 useQuery 鉤子。例如,在個人資料畫面上取得使用者個人資料。
  // 使用惰性查詢刷新直接取得第1頁
  const [triggerFetchFirstPage,{ 資料:lazyData }] = useLazyGetPostsQuery(); // useLazyquery 當你想要控制 api 呼叫時使用,例如按鈕點擊。

  const [createPost] = useCreatePostMutation();
  const [updatePost] = useUpdatePostMutation();
  const [deletePost] = useDeletePostMutation();

  useEffect(() => {
    如果(帖子){
      setPostsData((prevData) => (頁 === 1 ? posts : [...prevData, ...posts]));
    }
  }, [帖子, 頁]);

  // 登入處理程序
  const handleLogin = async () =>; {
    嘗試 {
      const 憑證 = { 使用者名稱:'emilys',密碼:'emilyspass' };
      等待登入(憑證);
      console.log('使用者設定檔', 使用者設定檔);
      重新取得使用者設定檔();
    } 捕獲(錯誤){
      console.error('登入失敗:', error);
    }
  };

  const handleRefresh = async () =>; {
    設定刷新(真);
    設定頁面(1); // 將頁面重設為 1 以進行下一個捲動
    setPostsData([]); // 清除資料以避免重複

    // 明確觸發第一頁獲取
    const { 資料 } = 等待觸發FetchFirstPage({ 頁數: 1, 限制: 10 });

    如果(數據){
      設定貼文資料(資料); // 將貼文資料設定為第一頁的結果
    }

    設定刷新(假);
  };

  // 建立一個新帖子,將其添加到頂部,然後重新獲取列表
  const handleCreatePost = async () =>; {
    如果(新帖子標題){
      const { data: newPost } = wait createPost({ title: newPostTitle, body: '新帖子內容' });
      設定新貼文標題('');
      setPostsData((prevData) => [newPost, ...prevData]);
      重新獲取();
    }
  };

  // 更新現有貼文並將「HASAN」新增至其標題中
  const handleUpdatePost = async (post) =>; {
    const { 資料:updatePost } = 等待 updatePost({
      id:帖子id,
      標題: `${post.title} HASAN`,
    });
    setPostsData((prevData) =>;
      prevData.map((item) => (item?.id === UpdatedPost?.id ?updatedPost : item))
    );
  };

  // 刪除貼文並立即將其從 UI 中刪除
  const handleDeletePost = async (id) =>; {
    等待deletePost(id);
    setPostsData((prevData) => prevData.filter((post) => post.id !== id));
  };

  // 加載更多帖子以實現無限滾動
  const loadMorePosts = () =>; {
    if (!isFetching) {
      setPage((上一頁) => 上一頁 1);
    }
  };

  // 切換模態可見性
  consttoggleModal = () =>; {
    setModalVisible(!isModalVisible);
  };

  if (isLoading && page === 1) return <text>正在載入...</text>;
  if (isError) return <text> 取得貼文時發生錯誤。 </text>;

  返回 (
    



  • MainApp 元件 (src/MainApp.js):
    • 狀態和掛鉤:管理本地狀態(例如,用於帖子分頁)和諸如 useLoginMutation 之類的掛鉤來觸發特定事件的操作。
    • 登入
      • 使用 useLoginMutation 登入用戶,然後觸發 refetchUserProfile 載入用戶設定檔資料。
      • 條件查詢:只有在有有效令牌時才取得使用者個人資料(跳過:!token),減少不必要的 API 呼叫。
    • 取得貼文
      • 使用 useGetPostsQuery 獲取分頁帖子,透過在用戶滾動時獲取更多數據來支援無限滾動。
      • 刷新控制項:允許用戶刷新貼文列表,對於行動裝置上的下拉式刷新功能很有用。
    • 建立、更新、刪除貼文
      • Create:呼叫createPost,立即更新貼文列表,新貼文位於頂部。
      • 更新:更新時將「HASAN」附加到貼文標題。
      • 刪除:刪除貼文並更新 UI,無需重新載入頁面,這要歸功於 deletePost 的快取失效。
    • 使用者介面元素
      • 模態顯示使用者個人資料。僅當載入使用者設定檔資料時才會出現設定檔按鈕,從而增強使用者體驗。
    • FlatList:以可捲動、分頁格式顯示帖子,增強可用性。

概括:

您的 React Native 應用程式使用 Redux Toolkit (RTK) 查詢 來實現高效的資料管理和 API 互動。設定包括:

  1. 存儲配置:帶有redux-persist 的Redux 存儲,用於跨應用程序會話保存特定數據,用於錯誤日誌記錄的自定義中間件,以及用於在開發模式下進行偵錯的Reactotron。

  2. 有 RTK 查詢的 API:

    • authApi 透過登入突變處理驗證,將令牌儲存在 Redux 中。
    • postsApi 為貼文提供 CRUD 操作,在新增、更新或刪除貼文時使用快取標籤自動刷新資料。
    • usersApi 使用基於動態令牌的授權標頭取得使用者設定檔。
  3. Auth Slice:管理身分驗證令牌並提供在登入/登出時設定或清除令牌的操作。

  4. 應用程式和主應用程式元件

    • 主應用程式將元件包裝在 Provider 和 PersistGate 中,確保在渲染之前載入狀態。
    • MainApp 管理貼文的取得、建立、更新和刪除。它有條件地載入資料(例如,僅當令牌存在時才取得使用者設定檔),支援分頁和無限滾動
    • 使用 FlatList 作為分頁貼文列表,使用模式作為個人資料,並使用基本樣式來實現乾淨、有組織的佈局。

完整程式碼->

以上是透過 RTK 查詢在 React Native 中高效處理數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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