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

首頁 web前端 js教程 透過 RTK 查詢在 React Native 中高效處理數(shù)據(jù)

透過 RTK 查詢在 React Native 中高效處理數(shù)據(jù)

Nov 30, 2024 am 10:01 AM

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

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

Efficient Data Handling in React Native with RTK Query

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

  1. 自動快取:RTK Query 快取數(shù)據(jù),並在數(shù)據(jù)失效時自動重新獲取,確保 UI 始終擁有最新數(shù)據(jù)。
  2. 快取失效:RTK 查詢使用標籤,讓您定義何時應重新取得某些資料。這有助於保持快取最新,無需手動更新資料。
  3. 自動產(chǎn)生的鉤子:RTK Query 為每個 API 端點建立鉤子,讓您可以使用簡單的 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 查詢如果:

    • 您已經(jīng)在使用 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)和網(wǎng)路請求的有用工具。這只在開發(fā)時激活,使調試更容易,而不影響生產(chǎn)。

  • 中介軟體:

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



2. RTK 查詢的 API 定義

RTK Query 透過自動產(chǎn)生 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 中。這可以實現(xiàn)對其他端點的安全性、經(jīng)過身份驗證的請求。

// 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:獲取分頁帖子,這意味著它以較小的區(qū)塊(頁面)檢索數(shù)據(jù),從而提高效能和載入時間。
      • createPost、updatePost 和 deletePost:其中每一個都執(zhí)行不同的操作(建立、更新或刪除貼文)。
    • 用於快取的標籤:每個端點都使用標籤(例如,{ 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 取得經(jīng)過驗證的使用者的個人資料,根據(jù) 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ā)模式下,此設定提供了一種強大的調試方法,無需添加額外的程式碼或改變生產(chǎn)效能。


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 確保在應用程式顯示之前持久載入數(shù)據(jù),減少載入時間不一致。

// 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(未定義,{
    跳過:!令牌,
  });

  // 取得分頁帖子
  常量{
    數(shù)據(jù):帖子,
    正在加載,
    正在獲取,
    是錯誤,
    重新獲取,
  } = useGetPostsQuery({ 頁數(shù), 限制: 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({ 頁數(shù): 1, 限制: 10 });

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

    設定刷新(假);
  };

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

  // 更新現(xiàn)有貼文並將「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));
  };

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

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

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

  返回 (
    



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

概括:

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

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

  2. 有 RTK 查詢的 API:

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

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

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

完整程式碼->

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

本網(wǎng)站聲明
本文內容由網(wǎng)友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權的內容,請聯(lián)絡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

視覺化網(wǎng)頁開發(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主要用於網(wǎng)頁開發(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。掌握這些要點能有效避免常見錯誤。

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

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

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

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

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

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

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

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標元素,冒泡是從目標元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數(shù)設為true實現(xiàn);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è)應用和大型系統(tǒng)。 2.JavaScript是動態(tài)類型、解釋型語言,主要用於網(wǎng)頁交互和前端開發(fā)。

See all articles