React Native:Reducer 在初始获取后变得未定义

问题描述 投票:0回答:1

我在 React Native 中的 Redux 设置遇到问题,其中有两个缩减程序:一个用于身份验证,另一个用于菜单。虽然身份验证缩减程序在整个应用程序中保留数据没有任何问题,但菜单缩减程序似乎有问题。调用

getMenu()
操作后,菜单状态最初会正确填充数据,但随后立即变为未定义。我正在寻求有关如何排查和解决此问题的建议。我希望能够在整个应用程序中保留菜单数据。

代码:

//store.js
import { configureStore, combineReducers } from "@reduxjs/toolkit";
import {
  persistStore,
  persistReducer,
} from "redux-persist";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { combineReducers } from "redux";

import authReducer from "./auth/authReducer";
import menuReducer from "./menu/menuReducer";

const rootPersistConfig = {
  key: "root",
  storage: AsyncStorage,
  keyPrefix: "redux-",
  whitelist: [],
};

const rootReducer = combineReducers({
  auth: authReducer,
  menu: menuReducer,
});

const persistedReducer = persistReducer(rootPersistConfig, rootReducer);

export const store = configureStore({
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false,
    }),
  reducer: persistedReducer,
});

export const persistor = persistStore(store);
//menuReducer.js
import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  menu: null,
  loading: false,
  error: null,
};

const menuSlice = createSlice({
  name: "menu",
  initialState,
  reducers: {
     setLoading: (state, action) => {
      state.loading = action.payload;
    },
    setError: (state, action) => {
      state.error = action.payload;
      state.loading = false;
    },
    setMenu: (state, action) => {
      state.menu = action.payload;
      state.loading = false;
    },
    clearMenu: (state) => {
      state.menu = null;
    },
    clearError: (state) => {
      state.error = null;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase("menu/getMenu/pending", (state) => {
        state.loading = true;
      })
      .addCase("menu/getMenu/fulfilled", (state, action) => {
        state.loading = false;
        state.menu = action.payload;
      })
      .addCase("menu/getMenu/rejected", (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  },
});
export const { setLoading, setError, setMenu, clearMenu, clearError } =
  menuSlice.actions;
export default menuSlice.reducer;

这是我如何用数据更新菜单状态:

//menuAction.js
export const getMenu = createAsyncThunk(
  "menu/getMenu",
  async ({ storeNumber, token }, { dispatch }) => {
    try {
      dispatch(setLoading(true));
      const menu = await GetMenuApi(storeNumber, token);
      dispatch(setMenu(menu));
      dispatch(clearError());
      dispatch(setLoading(false));
    } catch (error) {
      dispatch(setError(error));
    }
  }
);
//App.js
export default function App(){
  const { menu } = useSelector((state) => state.menu);
  const dispatch = useDispatch();
  const storeNumber = 1;
  const token = 'abc'

  console.log(menu) //logs correct data then immediately logs undefined

  const getMenuFunc= () => {
    dispatch(getMenu({ storeNumber, token }));
  };

  return(
   <View style={{flex:1}}>
    <Button onPress={getMenuFunc} title="get menu"/>
   </View>
  );
}

调用

getMenuFunc()
功能后,
console.log(menu)
首次正确记录菜单数据。然而,在随后调用
getMenuFunc()
时,
menu
变量变为
undefined
。有趣的是,在通过 Expo 重新加载应用程序并随后调用
getMenuFunc()
时,数据会再次检索,只是再次变为
undefined

reactjs react-native redux redux-toolkit redux-persist
1个回答
0
投票

您是否使用 PersistGate 包装了根组件?如果没有,那么您需要包装它,因为它会延迟应用程序 UI 的渲染,直到检索到持久状态并将其保存到 redux 为止。否则,您的应用程序将在状态保存到 Redux 存储之前加载,因此当您尝试访问状态时,您将得到未定义的信息,因为它在存储中不存在。

请检查下面的链接了解更多https://www.npmjs.com/package/redux-persist#:~:text=If%20you%20are%20using%20react%2C%20wrap%20your%20root%20component% 20with%20PersistGate。%20此%20延迟%20the%20rendering%20of%20your%20app%27s%20UI%20until%20your%20persisted%20state%20has%20been%20retrieved%20and%20saved%20to%20redux。%20NOTE%20the% 20PersistGate%20loading%20prop%20can%20be%20null%2C%20or

© www.soinside.com 2019 - 2024. All rights reserved.