1

我正在创建一个反应原生应用程序,我收到了这个警告。reducerPath "api" 处的 RTK-Query API 中间件尚未添加到商店。自动缓存收集、自动重新获取等功能将不可用。

我看到我的 api 没有被重新获取。

这是我的 rootReducer.ts 文件

import {combineReducers} from '@reduxjs/toolkit';
import { storiesApi } from 'src/services/storiesService'

const appReducer = combineReducers({
  [storiesApi.reducerPath]: storiesApi.reducer,
});

const rootReducer = (state, action) => {
  if (action.type === 'RESET_APP') {
    state = undefined;
  }
  return appReducer(state, action);
};

export const resetAppAction = () => dispatch => {
  console.log('Reset Redux Store');
  dispatch({type: 'RESET_APP'});
};

export default rootReducer;

这是我的 store.ts 文件

import { useDispatch as useReduxDispatch, useSelector as useReduxSelector } from 'react-redux';
import type { TypedUseSelectorHook } from 'react-redux';
import type { ThunkAction } from 'redux-thunk';
import type { Action } from '@reduxjs/toolkit';
import { configureStore } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query/react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {
  persistStore,
  persistReducer,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from "redux-persist"
import { encryptTransform } from 'redux-persist-transform-encrypt';
import thunk from 'redux-thunk';
import { ENABLE_REDUX_DEV_TOOLS } from 'src/constants';
import rootReducer from './rootReducer';
import { storiesApi } from 'src/services/storiesService'

const encryptor = encryptTransform({
  secretKey: 'my-super-secret-key-jrtec-soyaig',
  onError: function (error) {
    // Handle the error.
  },
});

const persistConfig = {
  // Root
  key: 'root',
  // Storage Method (React Native)
  storage: AsyncStorage,
  timeout: null,
  transforms: [encryptor],
};
const persistedReducer = persistReducer(persistConfig, rootReducer);

export const store = configureStore({
  reducer: persistedReducer,
  devTools: ENABLE_REDUX_DEV_TOOLS,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }).concat(
      thunk,
      storiesApi.middleware
    ),
});

// optional, but required for refetchOnFocus/refetchOnReconnect behaviors
// see `setupListeners` docs - takes an optional callback as the 2nd arg for customization
setupListeners(store.dispatch)

export const persistor = persistStore(store);

export type RootState = ReturnType<typeof store.getState>;

export type AppDispatch = typeof store.dispatch;

export type AppThunk = ThunkAction<void, RootState, null, Action<string>>;

export const useSelector: TypedUseSelectorHook<RootState> = useReduxSelector;

export const useDispatch = () => useReduxDispatch<AppDispatch>();

这是我正在使用 axios storiesService.ts 的服务

import { createApi, BaseQueryFn } from '@reduxjs/toolkit/query/react'
import { AxiosRequestConfig, AxiosError } from 'axios'
import responseCamelizerAxios from 'src/lib/axiosInstance';
const API_STORIES = '/api/stories/users/';

export interface IPost {
  createdAt: string;
  department: string;
  description: string;
  image: string[];
  likeStatus: boolean;
  likes: number;
  logo: string;
  organization: string;
  pk: string
  title: string
}

interface IListResponse {
  currentPage: number;
  pageSizeNews: number;
  results: IPost[]
  totalNews: number;
  totalPages: number;
}

export interface IChangeLikesResponse {
  data: {
    stories: {
      pk: number;
      like_active: boolean;
    },
  }
}

export interface IBodyChangeLikes {
  postId: number;
  likeStatus: boolean;
}

const axiosBaseQuery = (
  { baseUrl }: { baseUrl: string } = { baseUrl: '' }
): BaseQueryFn<
  {
    url?: string
    method: AxiosRequestConfig['method']
    body?: AxiosRequestConfig['data']
  },
  unknown,
  unknown
> =>
  async ({ url='', method, body }) => {
    try {
      const result = await responseCamelizerAxios({ url: baseUrl + url, method, data: body })
      console.log('result', result);
      return { data: result.data }
    } catch (axiosError) {
      // console.log('axiosError', axiosError);
      // console.log('axiosError', axiosError.response?.status);      
      let err = axiosError as AxiosError      
      return {
        error: { status: err.response?.status, data: err.response?.data },
      }
    }
  }

export const storiesApi = createApi({
  baseQuery: axiosBaseQuery({ baseUrl: API_STORIES }),
  endpoints: (build) => ({
    getStories: build.query<IListResponse, number | void>({
      query: (page = 1) => ({ url: `?page=${page}`, method: 'get' }),
    }),
    changeLikes: build.mutation<IChangeLikesResponse, IBodyChangeLikes>({
      query: ({postId, likeStatus}: IBodyChangeLikes ) => ({ 
        method: 'post', 
        body: {
          data: {
            stories: {
              pk: postId,
              like_active: likeStatus,
            },
          },
        }
      }),
    }),
  }),
})

export const { useGetStoriesQuery, useChangeLikesMutation } = storiesApi

我在我的页面上使用这个钩子来获取数据

  const { data, error, isLoading: isLoadingGetStories } = useGetStoriesQuery(page);

这是我的信息。你能告诉我我的代码有什么问题吗?

在此处输入图像描述

4

3 回答 3

1

您忘记添加 API 中间件。请参阅此处的文档。在此处输入图像描述

于 2021-12-02T08:10:40.070 回答
0

这是使用黑名单的更好解决方案

store.ts

    import { useDispatch as useReduxDispatch, useSelector as useReduxSelector } from 'react-redux';
    import type { TypedUseSelectorHook } from 'react-redux';
    import type { ThunkAction } from 'redux-thunk';
    import type { Action } from '@reduxjs/toolkit';
    import { configureStore } from '@reduxjs/toolkit';
    import { setupListeners } from '@reduxjs/toolkit/query/react';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    import {
      persistStore,
      persistReducer,
      FLUSH,
      REHYDRATE,
      PAUSE,
      PERSIST,
      PURGE,
      REGISTER,
    } from "redux-persist"
    import { encryptTransform } from 'redux-persist-transform-encrypt';
    import thunk from 'redux-thunk';
    import { ENABLE_REDUX_DEV_TOOLS } from 'src/constants';
    import rootReducer from './rootReducer';
    import { storiesApi } from 'src/services/storiesService'
    
    const encryptor = encryptTransform({
      secretKey: 'my-super-secret-key',
      onError: function (error) {
        // Handle the error.
      },
    });
    
    const persistConfig = {
      key: 'root',
      storage: AsyncStorage,
      blacklist: [
        storiesApi.reducerPath, 
      ],
      timeout: null,
      transforms: [encryptor],
    };
    const persistedReducer = persistReducer(persistConfig, rootReducer);
    
    export const store = configureStore({
      reducer: persistedReducer,
      devTools: ENABLE_REDUX_DEV_TOOLS,
      middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware({
          serializableCheck: {
            ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
          },
        }).concat(
          thunk,
          storiesApi.middleware,
        ),
    });
    
    // optional, but required for refetchOnFocus/refetchOnReconnect behaviors
    // see `setupListeners` docs - takes an optional callback as the 2nd arg for customization
    setupListeners(store.dispatch)
    
    export const persistor = persistStore(store);
    
    export type RootState = ReturnType<typeof store.getState>;
    
    export type AppDispatch = typeof store.dispatch;
    
    export type AppThunk = ThunkAction<void, RootState, null, Action<string>>;
    
    export const useSelector: TypedUseSelectorHook<RootState> = useReduxSelector;
    
    export const useDispatch = () => useReduxDispatch<AppDispatch>();

rootReducer.ts

import { combineReducers } from '@reduxjs/toolkit';
import { reducer as authReducer } from 'src/redux/slices/auth';
import { reducer as storiesReducer } from 'src/redux/slices/stories';
import { storiesApi } from 'src/services/storiesService'

const appReducer = combineReducers({
  auth: authReducer,
  stories: storiesReducer,
  [storiesApi.reducerPath]: storiesApi.reducer,
});

const rootReducer = (state, action) => {
  if (action.type === 'RESET_APP') {
    state = undefined;
  }
  return appReducer(state, action);
};

export const resetAppAction = () => dispatch => {
  console.log('Reset Redux Store');
  dispatch({ type: 'RESET_APP' });
};

export default rootReducer;
于 2021-09-30T21:56:13.163 回答
0

我能够保持状态和 rtk-query 一起改变我的 conconfigureStore

export const store = configureStore({
  reducer: {
    [storiesApi.reducerPath]: storiesApi.reducer,
    persistedReducer
  },
  devTools: ENABLE_REDUX_DEV_TOOLS,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }).concat(
      thunk,
      storiesApi.middleware
    ),
});

对于持久状态,可以以这种形式读取状态

  const isConnected2Internet = useSelector((state: RootState) => state.persistedReducer.notification.isConnected2Internet);
于 2021-09-29T18:08:05.567 回答