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

首頁(yè) web前端 js教程 通過(guò) RTK 查詢(xún)?cè)?React Native 中高效處理數(shù)據(jù)

通過(guò) RTK 查詢(xún)?cè)?React Native 中高效處理數(shù)據(jù)

Nov 30, 2024 am 10:01 AM

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

  • CRUD 操作
  • 分頁(yè)
  • Redux 通過(guò) RTK 查詢(xún)持久化
  • 多個(gè)基本 URL 使用
  • 受保護(hù)和公共路線(xiàn)
  • 緩存管理和失效

Efficient Data Handling in React Native with RTK Query

RTK 查詢(xún) 是內(nèi)置于 Redux Toolkit (RTK) 中的高級(jí)數(shù)據(jù)獲取和緩存工具。它通過(guò)為獲取、緩存和更新數(shù)據(jù)等常見(jiàn)任務(wù)生成 Redux 切片和掛鉤來(lái)簡(jiǎn)化 API 交互。主要功能包括:

  1. 自動(dòng)緩存:RTK Query 緩存數(shù)據(jù),并在數(shù)據(jù)失效時(shí)自動(dòng)重新獲取,確保 UI 始終擁有最新數(shù)據(jù)。
  2. 緩存失效:RTK 查詢(xún)使用標(biāo)簽,讓您定義何時(shí)應(yīng)重新獲取某些數(shù)據(jù)。這有助于保持緩存最新,無(wú)需手動(dòng)更新數(shù)據(jù)。
  3. 自動(dòng)生成的鉤子:RTK Query 為每個(gè) API 端點(diǎn)創(chuàng)建鉤子,允許您使用簡(jiǎn)單的 React 鉤子(useGetPostsQuery、useCreatePostMutation 等)調(diào)用 API。
  4. 錯(cuò)誤處理:包括通過(guò)中間件的自定義錯(cuò)誤處理,可以輕松捕獲和顯示錯(cuò)誤。
  5. 簡(jiǎn)化的 Redux 集成:RTK Query 直接與 Redux 集成,因此您不需要額外的庫(kù)來(lái)進(jìn)行全局狀態(tài)管理或緩存。

RTK 查詢(xún)與 React 查詢(xún)

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

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 查詢(xún)和 React 查詢(xún)之間進(jìn)行選擇:

  • 使用 RTK 查詢(xún)如果:

    • 您已經(jīng)在使用 Redux,并且想要一個(gè)集成的、簡(jiǎn)化的數(shù)據(jù)獲取解決方案。
    • 您需要在 Redux 中進(jìn)行集中式錯(cuò)誤處理和開(kāi)發(fā)工具集成。
  • 使用 React 查詢(xún) 如果:

    • 您想要一個(gè)更輕量級(jí)的設(shè)置,無(wú)需 Redux 依賴(lài)。
    • 您更喜歡單獨(dú)的服務(wù)器狀態(tài)管理,不需要全局應(yīng)用程序狀態(tài)。

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


Efficient Data Handling in React Native with RTK Query



1. 商店配置和設(shè)置

// 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 是保存應(yīng)用程序狀態(tài)的主要結(jié)構(gòu)。在您的設(shè)置中,它通過(guò) redux-persist 進(jìn)行了增強(qiáng),可以在本地保存 Redux 狀態(tài)的某些部分,因此即使應(yīng)用程序重新啟動(dòng),它們也會(huì)持續(xù)存在。

  • redux-persist:

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

  • 中間件:

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



2. RTK 查詢(xún)的 API 定義

RTK Query 通過(guò)自動(dòng)生成 Redux 切片、掛鉤和緩存來(lái)簡(jiǎn)化 API 調(diào)用。以下是您定義的 API 的詳細(xì)信息:

// 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):
    • 定義登錄突變,將用戶(hù)憑據(jù)(例如用戶(hù)名、密碼)發(fā)送到服務(wù)器進(jìn)行身份驗(yàn)證。
    • onQueryStarted:登錄成功后,它使用 setToken 操作將返回的令牌存儲(chǔ)在 Redux 中。這可以實(shí)現(xiàn)對(duì)其他端點(diǎn)的安全、經(jīng)過(guò)身份驗(yàn)證的請(qǐ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 包含多個(gè)與帖子交互的端點(diǎn)(獲取、創(chuàng)建、更新、刪除)。
      • getPosts:獲取分頁(yè)帖子,這意味著它以較小的塊(頁(yè)面)檢索數(shù)據(jù),從而提高性能和加載時(shí)間。
      • createPost、updatePost 和 deletePost:其中每一個(gè)都執(zhí)行不同的操作(創(chuàng)建、更新或刪除帖子)。
    • 用于緩存的標(biāo)簽:每個(gè)端點(diǎn)都使用標(biāo)簽(例如,{ type: 'Posts', id })自動(dòng)管理緩存失效和刷新。例如,創(chuàng)建或刪除帖子會(huì)使緩存失效,從而提示 getPosts 無(wú)需手動(dòng)干預(yù)即可獲取新數(shù)據(jù)。

// 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)過(guò)身份驗(yàn)證的用戶(hù)的個(gè)人資料,根據(jù) Redux 中的令牌設(shè)置授權(quán)標(biāo)頭。
    • Headers:prepareHeaders 動(dòng)態(tài)地將令牌附加到每個(gè)請(qǐng)求(如果可用),從而允許安全且授權(quán)的 API 請(qǐng)求。


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),在本例中為用戶(hù)身份驗(yàn)證。
  • 狀態(tài)管理:authSlice 保留用戶(hù)的令牌,用于訪(fǎng)問(wèn)受保護(hù)的 API 端點(diǎn)。
  • 行動(dòng)
    • setToken:在 Redux 狀態(tài)中存儲(chǔ)身份驗(yàn)證令牌。
    • logout:從 Redux 中清除令牌,有效地將用戶(hù)注銷(xiāo)。


4. 用于調(diào)試的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 是一個(gè)調(diào)試工具,有助于跟蹤 Redux 狀態(tài)更改、監(jiān)控 API 請(qǐng)求和檢查日志。
  • Setup:配置為捕獲 console.log 輸出和 Redux 操作。在開(kāi)發(fā)模式下,此設(shè)置提供了一種強(qiáng)大的調(diào)試方法,無(wú)需添加額外的代碼或改變生產(chǎn)性能。


5. 主要應(yīng)用組件

// 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;
  • 應(yīng)用程序組件(src/App.js)
    • App 組件將整個(gè)應(yīng)用程序包裝在 Provider(以使 Redux 可用)和 PersistGate(延遲渲染,直到檢索到持久狀態(tài))中。
    • PersistGate 確保在應(yīng)用程序顯示之前持久加載數(shù)據(jù),減少加載時(shí)間不一致。

// src/MainApp.js
從 'react' 導(dǎo)入 React, { useEffect, useState };
進(jìn)口 {
  活動(dòng)指示器,
  按鈕,
  平面列表,
  莫代爾,
  刷新控制,
  樣式表,
  文本,
  文本輸入,
  看法,
來(lái)自 'react-native';
從 'react-native-safe-area-context' 導(dǎo)入 { SafeAreaView } ;
從 'react-redux' 導(dǎo)入 { useDispatch, useSelector };
從 './api/authApi' 導(dǎo)入 { useLoginMutation } ;
進(jìn)口 {
  使用CreatePostMutation,
  使用DeletePostMutation,
  使用GetPosts查詢(xún),
  使用LazyGetPosts查詢(xún),
  使用更新后突變,
來(lái)自 './api/postsApi';
從'./api/usersApi'導(dǎo)入{useGetUserProfileQuery};
導(dǎo)入{注銷(xiāo)}來(lái)自“./features/auth/authSlice”;

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

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

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

  // 當(dāng)令牌可用時(shí)獲取用戶(hù)配置文件
  const { 數(shù)據(jù):userProfile,重新獲?。簉efetchUserProfile } = useGetUserProfileQuery(未定義,{
    跳過(guò):!令牌,
  });

  // 獲取分頁(yè)帖子
  常量{
    數(shù)據(jù):帖子,
    正在加載,
    正在獲取,
    是錯(cuò)誤,
    重新獲取,
  } = useGetPostsQuery({ 頁(yè)數(shù), 限制: 10 }); // 當(dāng)你想在屏幕加載時(shí)獲取數(shù)據(jù)時(shí),使用 useQuery 鉤子。例如,在個(gè)人資料屏幕上獲取用戶(hù)個(gè)人資料。
  // 使用惰性查詢(xún)刷新直接獲取第1頁(yè)
  const [triggerFetchFirstPage,{ 數(shù)據(jù):lazyData }] = useLazyGetPostsQuery(); // useLazyquery 當(dāng)你想要控制 api 調(diào)用時(shí)使用,比如按鈕點(diǎn)擊。

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

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

  // 登錄處理程序
  const handleLogin = async () =>; {
    嘗試 {
      const 憑證 = { 用戶(hù)名:'emilys',密碼:'emilyspass' };
      等待登錄(憑據(jù));
      console.log('用戶(hù)配置文件', 用戶(hù)配置文件);
      重新獲取用戶(hù)配置文件();
    } 捕獲(錯(cuò)誤){
      console.error('登錄失?。?, error);
    }
  };

  const handleRefresh = async () =>; {
    設(shè)置刷新(真);
    設(shè)置頁(yè)面(1); // 將頁(yè)面重置為 1 以進(jìn)行下一個(gè)滾動(dòng)
    setPostsData([]); // 清除數(shù)據(jù)以避免重復(fù)

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

    如果(數(shù)據(jù)){
      設(shè)置帖子數(shù)據(jù)(數(shù)據(jù)); // 將帖子數(shù)據(jù)設(shè)置為第一頁(yè)的結(jié)果
    }

    設(shè)置刷新(假);
  };

  // 創(chuàng)建一個(gè)新帖子,將其添加到頂部,然后重新獲取列表
  const handleCreatePost = async () =>; {
    如果(新帖子標(biāo)題){
      const { data: newPost } = wait createPost({ title: newPostTitle, body: '新帖子內(nèi)容' });
      設(shè)置新帖子標(biāo)題('');
      setPostsData((prevData) => [newPost, ...prevData]);
      重新獲?。ǎ?;
    }
  };

  // 更新現(xiàn)有帖子并將“HASAN”添加到其標(biāo)題中
  const handleUpdatePost = async (post) =>; {
    const { 數(shù)據(jù):updatePost } = 等待 updatePost({
      id:帖子id,
      標(biāo)題: `${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));
  };

  // 加載更多帖子以實(shí)現(xiàn)無(wú)限滾動(dòng)
  const loadMorePosts = () =>; {
    if (!isFetching) {
      setPage((上一頁(yè)) => 上一頁(yè) 1);
    }
  };

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

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

  返回 (
    



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

概括:

您的 React Native 應(yīng)用程序使用 Redux Toolkit (RTK) 查詢(xún) 來(lái)實(shí)現(xiàn)高效的數(shù)據(jù)管理和 API 交互。設(shè)置包括:

  1. 存儲(chǔ)配置:帶有 redux-persist 的 Redux 存儲(chǔ),用于跨應(yīng)用程序會(huì)話(huà)保存特定數(shù)據(jù),用于錯(cuò)誤日志記錄的自定義中間件,以及用于在開(kāi)發(fā)模式下進(jìn)行調(diào)試的 Reactotron。

  2. 帶 RTK 查詢(xún)的 API:

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

  4. 應(yīng)用程序和主應(yīng)用程序組件

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

完整代碼->

以上是通過(guò) RTK 查詢(xún)?cè)?React Native 中高效處理數(shù)據(jù)的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線(xiàn)人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

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

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門(mén)話(huà)題

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

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

JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 Jun 19, 2025 am 12:40 AM

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

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

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

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

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

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

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

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

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

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

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

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

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

See all articles