国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

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

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

Nov 30, 2024 am 10:01 AM

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

  • 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 端點創(chuàng)建鉤子,允許您使用簡單的 React 鉤子(useGetPostsQuery、useCreatePostMutation 等)調用 API。
  4. 錯誤處理:包括通過中間件的自定義錯誤處理,可以輕松捕獲和顯示錯誤。
  5. 簡化的 Redux 集成:RTK Query 直接與 Redux 集成,因此您不需要額外的庫來進行全局狀態(tài)管理或緩存。

RTK 查詢與 React 查詢

React QueryRTK Query 都提供了 React 應用程序中的數據獲取和緩存解決方案,但它們具有不同的優(yōu)勢和用例:

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 中進行集中式錯誤處理和開發(fā)工具集成。
  • 使用 React 查詢 如果:

    • 您想要一個更輕量級的設置,無需 Redux 依賴。
    • 您更喜歡單獨的服務器狀態(tài)管理,不需要全局應用程序狀態(tài)。

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


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 是保存應用程序狀態(tài)的主要結構。在您的設置中,它通過 redux-persist 進行了增強,可以在本地保存 Redux 狀態(tài)的某些部分,因此即使應用程序重新啟動,它們也會持續(xù)存在。

  • redux-persist:

    • 用途:幫助保持部分 Redux 狀態(tài)在應用程序會話中保持不變。
    • 配置:persistConfig 對象指定 auth、postsApi 和 usersApi 不應被持久化(列入黑名單),這意味著它們的數據會在應用程序重新啟動時重置。
    • persistReducer 將減速器配置與持久化功能結合起來。
  • 增強器:自定義增強器用于在開發(fā)模式下集成Reactotron,這是一個調試 Redux 操作、狀態(tài)和網絡請求的有用工具。這只在開發(fā)時激活,使調試更容易,而不影響生產。

  • 中間件:

    • RTK 查詢中間件(postsApi.middleware、usersApi.middleware、authApi.middleware)添加自動緩存管理功能,提高數據獲取效率。
    • rtkQueryErrorLogger:自定義中間件在 API 調用失敗時記錄錯誤。它使用 RTK Query 的 isRejectedWithValue 函數來捕獲和處理錯誤,允許您提醒用戶有關問題或采取其他操作。
  • setupListeners:此功能可以在發(fā)生某些事件時自動重新獲取數據,例如當應用程序重新獲得焦點或從后臺恢復時,為用戶提供新鮮數據,而無需手動刷新。



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):
    • 定義登錄突變,將用戶憑據(例如用戶名、密碼)發(fā)送到服務器進行身份驗證。
    • 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 包含多個與帖子交互的端點(獲取、創(chuàng)建、更新、刪除)。
      • getPosts:獲取分頁帖子,這意味著它以較小的塊(頁面)檢索數據,從而提高性能和加載時間。
      • createPost、updatePost 和 deletePost:其中每一個都執(zhí)行不同的操作(創(chuàng)建、更新或刪除帖子)。
    • 用于緩存的標簽:每個端點都使用標簽(例如,{ type: 'Posts', id })自動管理緩存失效和刷新。例如,創(chuàng)建或刪除帖子會使緩存失效,從而提示 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 動態(tài)地將令牌附加到每個請求(如果可用),從而允許安全且授權的 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 切片管理特定的狀態(tài),在本例中為用戶身份驗證。
  • 狀態(tài)管理:authSlice 保留用戶的令牌,用于訪問受保護的 API 端點。
  • 行動
    • setToken:在 Redux 狀態(tài)中存儲身份驗證令牌。
    • 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 狀態(tài)更改、監(jiān)控 API 請求和檢查日志。
  • Setup:配置為捕獲 console.log 輸出和 Redux 操作。在開發(fā)模式下,此設置提供了一種強大的調試方法,無需添加額外的代碼或改變生產性能。


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(延遲渲染,直到檢索到持久狀態(tài))中。
    • 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,重新獲?。簉efetchUserProfile } = 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([]); // 清除數據以避免重復

    // 顯式觸發(fā)第一頁獲取
    const { 數據 } = 等待觸發(fā)FetchFirstPage({ 頁數: 1, 限制: 10 });

    如果(數據){
      設置帖子數據(數據); // 將帖子數據設置為第一頁的結果
    }

    設置刷新(假);
  };

  // 創(chuàng)建一個新帖子,將其添加到頂部,然后重新獲取列表
  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);
    }
  };

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

  if (isLoading && page === 1) return <text>正在加載...</text>;
  if (isError) return <text> 獲取帖子時出錯。</text>;

  返回 (
    



  • MainApp 組件 (src/MainApp.js):
    • 狀態(tài)和掛鉤:管理本地狀態(tài)(例如,用于帖子分頁)和諸如 useLoginMutation 之類的掛鉤來觸發(fā)特定事件的操作。
    • 登錄
      • 使用 useLoginMutation 登錄用戶,然后觸發(fā) refetchUserProfile 加載用戶配置文件數據。
      • 條件查詢:僅在存在有效令牌時才獲取用戶個人資料(跳過:!token),減少不必要的 API 調用。
    • 獲取帖子
      • 使用 useGetPostsQuery 獲取分頁帖子,通過在用戶滾動時獲取更多數據來支持無限滾動。
      • 刷新控件:允許用戶刷新帖子列表,對于移動設備上的下拉刷新功能很有用。
    • 創(chuàng)建、更新、刪除帖子
      • Create:調用createPost,立即更新帖子列表,新帖子位于頂部。
      • 更新:更新時將“HASAN”附加到帖子標題。
      • 刪除:刪除帖子并更新 UI,無需重新加載頁面,這要歸功于 deletePost 的緩存失效。
    • 用戶界面元素
      • 模態(tài)顯示用戶個人資料。僅當加載用戶配置文件數據時才會出現配置文件按鈕,從而增強用戶體驗。
    • FlatList:以可滾動、分頁格式顯示帖子,增強可用性。

概括:

您的 React Native 應用程序使用 Redux Toolkit (RTK) 查詢 來實現高效的數據管理和 API 交互。設置包括:

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

  2. 帶 RTK 查詢的 API:

    • authApi 通過登錄突變處理身份驗證,將令牌存儲在 Redux 中。
    • postsApi 為帖子提供 CRUD 操作,在添加、更新或刪除帖子時使用緩存標簽自動刷新數據。
    • usersApi 使用基于動態(tài)令牌的授權標頭獲取用戶配置文件。
  3. Auth Slice:管理身份驗證令牌并提供在登錄/注銷時設置或清除令牌的操作。

  4. 應用程序和主應用程序組件

    • 主應用程序將組件包裝在 Provider 和 PersistGate 中,確保在渲染之前加載狀態(tài)。
    • MainApp 管理帖子的獲取、創(chuàng)建、更新和刪除。它有條件地加載數據(例如,僅當令牌存在時才獲取用戶配置文件),支持分頁和無限滾動
    • 使用 FlatList 作為分頁帖子列表,使用模式作為個人資料,并使用基本樣式來實現干凈、有組織的布局。

完整代碼->

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

本站聲明
本文內容由網友自發(fā)貢獻,版權歸原作者所有,本站不承擔相應法律責任。如您發(fā)現有涉嫌抄襲侵權的內容,請聯系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅動的應用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用于不同的應用場景。Java用于大型企業(yè)和移動應用開發(fā),而JavaScript主要用于網頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創(chuàng)建Date對象有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

為什么要將標簽放在的底部? 為什么要將標簽放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript:探索用于高效編碼的數據類型 JavaScript:探索用于高效編碼的數據類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

什么是在DOM中冒泡和捕獲的事件? 什么是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標元素,冒泡是從目標元素向上傳播到頂層。1.事件捕獲通過addEventListener的useCapture參數設為true實現;2.事件冒泡是默認行為,useCapture設為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委托,提高動態(tài)內容處理效率;5.捕獲可用于提前攔截事件,如日志記錄或錯誤處理。了解這兩個階段有助于精確控制JavaScript響應用戶操作的時機和方式。

Java和JavaScript有什么區(qū)別? Java和JavaScript有什么區(qū)別? Jun 17, 2025 am 09:17 AM

Java和JavaScript是不同的編程語言。1.Java是靜態(tài)類型、編譯型語言,適用于企業(yè)應用和大型系統。2.JavaScript是動態(tài)類型、解釋型語言,主要用于網頁交互和前端開發(fā)。

See all articles