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

? ? ????? JS ???? RTK ??? ??? React Native? ???? ??? ??

RTK ??? ??? React Native? ???? ??? ??

Nov 30, 2024 am 10:01 AM

? ????? ?? ??? ??? ????.

  • CRUD ??
  • ??? ??
  • RTK ??? ??? Redux Persist
  • ?? ?? URL ??
  • ??? ?? ??
  • ?? ?? ? ???

Efficient Data Handling in React Native with RTK Query

RTK ??? Redux Toolkit(RTK)? ??? ?? ??? ???? ? ?? ?????. ??? ????, ??, ????? ?? ???? ??? ?? Redux ???? ? ??? ???? API ?? ??? ??????. ?? ??? ??? ????:

  1. ?? ??: RTK ??? ???? ???? ???? ????? ???? ?? ????? UI? ?? ?? ???? ?????.
  2. ?? ???: ??? ???? RTK ??? ?? ?? ???? ?? ???? ?? ??? ??? ? ????. ??? ?? ???? ???? ?????? ??? ??? ?? ??? ??? ? ????.
  3. ?? ?? ??: RTK ??? ? API ?????? ?? ??? ????? ??? React ??(useGetPostsQuery, useCreatePostMutation ?)? ???? API? ??? ? ????.
  4. ?? ??: ????? ?? ??? ?? ??? ???? ?? ??? ?? ???? ??? ? ????.
  5. ???? Redux ??: RTK ??? Redux? ?? ????? ?? ?? ?? ?? ??? ?? ?? ?????? ???? ????.

RTK ??? React ??

React ??? RTK ??? ?? 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 ??? Redux ?? ??????? ??? ??, React ??? 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 ???? ??????? ??? ???? ?? ?????. ???? Redux ??? ?? ??? ??? ???? redux-persist? ???? ?? ?? ???? ?????.

  • redux-???:

    • ??: Redux ??? ??? ? ?? ??? ?? ????? ???? ? ??? ???.
    • ??: persistConfig ??? auth, postApi ? usersApi? ???? ???(?????? ??) ?????. ?, ?? ?? ??? ? ?? ???? ??????.
    • persistReducer? ??? ??? ??? ??? ?????.
  • Enhancer: ??? ?? Enhancer? Redux ??, ?? ? ???? ??? ????? ? ??? ??? Reactotron? ?? ??? ???? ? ?????. ?? ?? ??? ?????? ????? ??? ?? ?? ???? ? ?????.

  • ????:

    • RTK ?? ????(postsApi.middleware, usersApi.middleware, authApi.middleware)? ?? ?? ?? ??? ???? ??? ????? ????? ????.
    • rtkQueryErrorLogger: API ??? ??? ? ??? ?? ????? ??? ?????. RTK ??? isRejectedWithValue ??? ???? ??? ???? ????? ????? ??? ?? ???? ?? ??? ?? ? ????.
  • setupListeners: ? ??? ???? ?? ???? ?? ??? ??????? ?? ??? ?? ?? ?? ???? ??? ? ???? ???? ?? ??? ? ?? ???? ?? ?? ?? ?? ????? ??? ???? ??? ? ????.



2. RTK ??? ??? API ??

RTK ??? 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? ??? ???? Authorization ??? ?????.
    • ??: prepareHeaders? ??? ?? ?? ??? ????? ???? ???? ???? ??? API ??? ?????.


3. ?? ????(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 ??? ??????, ??? ???? ? ??? ?? ??? ?????.
  • ??: 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
import React, { useEffect, useState } from 'react';
?? {
  ?????,
  ??,
  ?????,
  ??,
  ???????,
  ?????,
  ???,
  ??? ??,
  ??,
} '?? ????'??;
'react-native-safe-area-context'?? { SafeAreaView }? ?????.
import { useDispatch, useSelector } from 'react-redux';
import { useLoginMutation } from './api/authApi';
?? {
  useCreatePostMutation,
  useDeletePostMutation,
  useGetPostsQuery,
  useLazyGetPostsQuery,
  useUpdatePostMutation,
} './api/postsApi'??;
import { useGetUserProfileQuery } from './api/usersApi';
???? { ???? }'./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 ?? = useSelector((state) => state.auth.token);

  // ??? ????
  const [login, { isLoading: isLoggingIn }] = useLoginMutation();

  // ??? ??? ? ?? ? ??? ???? ?????.
  const { ???: userProfile, ?? ????: refetchUserProfile } = useGetUserProfileQuery(???? ??, {
    ????: !??,
  });

  // ???? ??? ???? ?????.
  const {
    ???: ???,
    ?? ?,
    ???? ?,
    isError,
    ?? ????,
  } = useGetPostsQuery({ ???, ??: 10 }); // useQuery ??? ?? ?? ? ???? ????? ??? ?????. ?? ?? ??? ???? ??? ???? ?????.
  // ??? 1? ?? ???? ?? ???? ?? ??? ?????.
  const [triggerFetchFirstPage, { data:lazyData }] = useLazyGetPostsQuery(); // useLazyquery? ?? ??? ?? API ??? ????? ??? ?????.

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

  useEffect(() => {
    if (???) {
      setPostsData((prevData) => (??? === 1 ? ???: [...prevData, ...???]));
    }
  }, [???, ???]);

  // ??? ???
  const handlerLogin = async () => {
    ???? {
      const ?? ?? = { ??? ??: 'emilys', ????: 'emilyspass' };
      ???? ?????(?? ??);
      console.log('userProfile', userProfile);
      refetchUserProfile();
    } ??(??) {
      console.error('??? ??:', error);
    }
  };

  const handlerRefresh = async () => {
    setRefreshing(true);
    setPage(1); // ?? ???? ?? ???? 1? ??????.
    setPostsData([]); // ??? ??? ?? ???? ????.

    // ? ?? ??? ????? ????? ??????.
    const { data } = TriggerFetchFirstPage({ ???: 1, ??: 10 })? ?????.

    if (???) {
      setPostsData(???); // ??? ???? ? ?? ???? ??? ?????.
    }

    setRefreshing(false);
  };

  // ? ???? ???? ??? ???? ??? ?? ?????.
  const handlerCreatePost = async () => {
    if (newPostTitle) {
      const { data: newPost } = createPost({ title: newPostTitle, body: '? ??? ???' })? ???? ????.
      setNewPostTitle('');
      setPostsData((prevData) => [newPost, ...prevData]);
      ?? ????();
    }
  };

  // ?? ???? ?????? ??? "HASAN"? ?????.
  const handlerUpdatePost = ???(???) => {
    const { data:updatePost } = updatePost? ?????({
      id: post.id,
      ??: `${post.title} ??`,
    });
    setPostsData((prevData) =>
      prevData.map((item) => (item?.id ===updatePost?.id ?updatePost : item))
    );
  };

  // ???? ???? UI?? ?? ?????.
  const handlerDeletePost = async (id) => {
    deletePost(id)? ?????;
    setPostsData((prevData) => prevData.filter((post) => post.id !== id));
  };

  // ?? ???? ?? ? ?? ??? ??
  const loadMorePosts = () => {
    if (!isFetching) {
      setPage((prevPage) => prevPage 1);
    }
  };

  // ?? ??? ??
  const ???? = () => {
    setModalVisible(!isModalVisible);
  };

  if (isLoading && page === 1) return <Text>Loading...</Text>
  if (isError) return <Text>??? ???? ??.</Text>

  ?? (
    <SafeAreaView>



<ul>
<li>
<strong>MainApp ?? ??(src/MainApp.js)</strong>:

<ul>
<li>
<strong>?? ? ??</strong>: ?? ??(?: ??? ??? ??) ? useLoginMutation? ?? ??? ???? ?? ???? ?? ??? ??????.</li>
<li>
<strong>???</strong>:

<ul>
<li>useLoginMutation? ???? ???? ???? ?? refetchUserProfile? ????? ??? ??? ???? ?????.</li>
<li>
<em>??? ??</em>: ??? ??? ??? ?? ??? ???? ?????(????: !token) ???? API ??? ????.</li>
</ul>


</li>

<li>

<strong>??? ???? ?</strong>:

<ul>
<li>useGetPostsQuery? ???? ???? ??? ???? ???? ???? ???? ? ? ?? ???? ??? ?? ???? ?????.</li>
<li>
<em>???? ??</em>: ???? ??? ??? ?? ?? ? ???, ????? ??? ?? ?? ??? ?????.</li>
</ul>


</li>

<li>

<strong>??? ??, ????, ??</strong>:

<ul>
<li>
<em>Create</em>: createPost? ???? ??? ??? ??? ? ???? ?? ???????.</li>
<li>
<em>????</em>: ???? ? ??? ??? "HASAN"? ?????.</li>
<li>
<em>??</em>: deletePost? ?? ??? ??? ???? ?? ??? ?? ?? ???? ???? UI? ???????.</li>
</ul>


</li>

<li>

<strong>UI ??</strong>:

<ul>
<li>??? ??? ???? ?????. ??? ??? userProfile ???? ??? ???? ????? ??? ??? ?????.</li>
</ul>


</li>

<li>

<strong>FlatList</strong>: ???? ??? ???? ???? ??? ???? ???? ???? ????.</li>

</ul>

</li>

</ul>


<hr>

<h2>
  
  
  ??:
</h2>

<p>React Native ?? ???? ??? ?? ? API ?? ??? ?? <strong>Redux Toolkit(RTK) ??</strong>? ?????. ???? ??? ?????.</p>

<ol>
<li><p><strong>??? ??</strong>: ? ?? ???? ?? ???? ???? ?? redux-persist, ?? ??? ?? ??? ????, ?? ???? ???? ?? Reactotron? ?? Redux ???.</p></li>
<li>
<p><strong>RTK ??? ??? API</strong>:</p><ul>
<li>
<strong>authApi</strong>? ??? ???? ??? ???? ??? Redux? ?????.</li>
<li>
<strong>postsApi</strong>? ???? ??, ???? ?? ??? ? ?? ??? ???? ???? ???? ?? ??? ???? ?? CRUD ??? ?????.</li>
<li>
<strong>usersApi</strong>? ?? ?? ?? ?? ??? ???? ??? ???? ?????.</li>
</ul>
</li>
<li><p><strong>Auth Slice</strong>: ?? ??? ???? ???/???? ? ??? ????? ???? ??? ?????.</p></li>
<li>
<p><strong>? ? MainApp ????</strong>:</p>

<ul>
<li>?? ?? Provider ? PersistGate? ?? ??? ???? ??? ?? ??? ????? ???.</li>
<li>
MainApp? ??? ????, ??, ???? ? ??? ?????. ???? ???? ????(?: ??? ??? ?? ??? ??? ????) ??? ?? ? ?? ???? ?????. </li>
<li>???? ??? ??? ???? FlatList? ????, ????? ??? ????, ???? ??? ????? ?? ?? ???? ?????.</li>
</ul>
</li>
</ol>

<blockquote>
<p>?? ??->



          

            
        

? ??? RTK ??? ??? React Native? ???? ??? ??? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!

? ????? ??
? ?? ??? ????? ???? ??? ??????, ???? ?????? ????. ? ???? ?? ???? ?? ??? ?? ????. ???? ??? ???? ???? ??? ?? admin@php.cn?? ?????.

? AI ??

Undresser.AI Undress

Undresser.AI Undress

???? ?? ??? ??? ?? AI ?? ?

AI Clothes Remover

AI Clothes Remover

???? ?? ???? ??? AI ?????.

Video Face Swap

Video Face Swap

??? ??? AI ?? ?? ??? ???? ?? ???? ??? ?? ????!

???

??? ??

???++7.3.1

???++7.3.1

???? ?? ?? ?? ???

SublimeText3 ??? ??

SublimeText3 ??? ??

??? ??, ???? ?? ????.

???? 13.0.1 ???

???? 13.0.1 ???

??? PHP ?? ?? ??

???? CS6

???? CS6

??? ? ?? ??

SublimeText3 Mac ??

SublimeText3 Mac ??

? ??? ?? ?? ?????(SublimeText3)

???

??? ??

?? ????
1783
16
Cakephp ????
1727
56
??? ????
1577
28
PHP ????
1442
31
???
Java vs. JavaScript : ??? ????? Java vs. JavaScript : ??? ????? Jun 20, 2025 am 12:27 AM

Java ? JavaScript? ?? ?? ????? ??? ?? ?? ?? ???? ????? ?????. Java? ??? ? ??? ?????? ??? ???? JavaScript? ?? ? ??? ??? ?????.

JavaScript ?? : ?? ?? JavaScript ?? : ?? ?? Jun 19, 2025 am 12:40 AM

JavaScriptCommentsareEnsentialformaining, ?? ? ???? 1) Single-LinecommentsERUSEDFORQUICKEXPLANATIONS.2) Multi-linecommentSexplaincleClexLogicOrprovidedEdeDDocumentation.3) inlineecommentsClarifySpecificPartSofcode.bestPractic

JS? ??? ???? ???? ??? JS? ??? ???? ???? ??? Jul 01, 2025 am 01:27 AM

JavaScript?? ??? ??? ?? ? ? ?? ??? ???????. 1. ?? ??? ??? ???? ?? ??? ????. ISO ?? ???? ???? ???? ???? ?? ????. 2. ?? ??? ?? ???? ??? ?? ???? ??? ? ??? ? ?? 0?? ????? ?? ??????. 3. ?? ?? ???? ???? ???? ?? ?????? ??? ? ????. 4. Luxon? ?? ???? ???? ?????? ???? ?? ????. ??? ?? ???? ????? ???? ??? ????? ?? ? ????.

? ? ???  ??? ?? ???? ??? ?????? ? ? ??? ??? ?? ???? ??? ?????? Jul 02, 2025 am 01:22 AM

TAGGSATTHEBOTTOMOFABLOGPOSTORWEBPAGESERVESPRACTICALPURSEO, USEREXPERIENCE, andDESIGN.1.ITHELPSWITHEOBYOWNSESPORENGENSTOESTOCESKESKERKESKERKERKERDER-RELEVANTTAGSWITHOUTHINGTEMAINCONTENT.2.ITIMPROVESEREXPERKEEPINGTOPONTEFOCUSOFOFOFOCUSOFOFOFOCUCUSONTHEATECLL

JavaScript vs. Java : ?????? ??? ? ?? JavaScript vs. Java : ?????? ??? ? ?? Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforwebDevelopment, whithjavaisbetterforlarge-scalebackendsystemsandandandoidapps.1) javascriptexcelsincreatinginteractivewebexperiences withitsdynatureanddommanipulation.2) javaoffersstrongtypingandobject-Orientededededededededededededededededdec

JavaScript : ???? ????? ??? ?? ?? JavaScript : ???? ????? ??? ?? ?? Jun 20, 2025 am 12:46 AM

javascriptassevenfundamentalDatatatypes : ??, ???, ??, unull, ??, ? symbol.1) ?? seAdouble-precisionformat, ??? forwidevaluerangesbutbecautiouswithfatingfointarithmetic.2) stringsareimmutable, useefficientconcatenationmethendsf

DOM?? ??? ?? ? ? ??? ?????? DOM?? ??? ?? ? ? ??? ?????? Jul 02, 2025 am 01:19 AM

??? ?? ? ??? DOM?? ??? ??? ? ?????. ??? ?? ????? ?? ??????, ??? ?? ???? ?? ????????. 1. ??? ??? addeventListener? usecapture ?? ??? true? ???? ?????. 2. ??? ??? ?? ???? usecapture? ???? ????? ?????. 3. ??? ??? ??? ??? ???? ? ??? ? ????. 4. ??? ?? ?? ?? ??? ?? ??? ??????? ??? ???? ?????. 5. ??? ?? ?? ?? ??? ?? ???? ?? ???? ? ??? ? ????. ? ? ??? ???? ???? JavaScript? ??? ??? ??? ????? ???? ???? ??? ??????.

Java? JavaScript? ???? ?????? Java? JavaScript? ???? ?????? Jun 17, 2025 am 09:17 AM

Java? JavaScript? ?? ????? ?????. 1. Java? ???? ???? ??? ? ??? ?????? ?????? ? ?? ???? ?????. 2. JavaScript? ?? ? ?? ?? ? ??? ?? ??? ???? ??? ? ?? ? ?? ?????.

See all articles