如何在React Native Expo中从布局文件更新redux存储

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

我正在构建一个博览会应用程序,并使用

react-redux
管理状态,因此我的
<Provider>
位于顶层 _layout 文件中。

我的问题是我正在处理博览会通知,我需要通过通知获取标题、正文和从服务器接收的一些数据,并将其发送到商店供以后使用,但是当我尝试发送时,我得到了一个错误提示:

找不到react-redux上下文值

我意识到发生此错误是因为我尝试在将整个应用程序包装在 redux 中之前使用调度

<Provider>
但我不知道如何做到这一点。下面是我的代码。

import React from "react";
import { Stack, SplashScreen } from "expo-router";
import { useEffect } from "react";
import { useFonts } from "expo-font";
import FontAwesome from "@expo/vector-icons/FontAwesome";
import { Provider } from "react-redux";
import { persistor, store } from "../src/redux/store/store";
import { PersistGate } from "redux-persist/integration/react";
import * as Notifications from "expo-notifications";
import { router } from "expo-router";
import { useDispatch } from "react-redux";
import { addMessage } from "../src/redux/slice/system-messages";

export {
  // Catch any errors thrown by the Layout component.
  ErrorBoundary,
} from "expo-router";

export const unstable_settings = {
  // Ensure that reloading on `/modal` keeps a back button present.
  initialRouteName: "(tabs)",
};

// Prevent the splash screen from auto-hiding before asset loading is complete.
SplashScreen.preventAutoHideAsync();

function saveNotificationResponse() {
  const dispatcher = useDispatch();
  const subscription = Notifications.addNotificationResponseReceivedListener(
    (response) => {
      console.log(response.notification.request.content.data);
      dispatcher(addMessage(response.notification.request.content.data));
    }
  );

  return () => {
    subscription.remove();
  };
}

export default function _layout() {
  useEffect(() => {
    saveNotificationResponse();
  }, []);

  const [loaded, error] = useFonts({
    SpaceMono: require("../src/assets/fonts/SpaceMono-Regular.ttf"),
    DMBold: require("../src/assets/fonts/DMSans-Bold.ttf"),
    DMMedium: require("../src/assets/fonts/DMSans-Medium.ttf"),
    DMRegular: require("../src/assets/fonts/DMSans-Regular.ttf"),
    ...FontAwesome.font,
  });

  // Expo Router uses Error Boundaries to catch errors in the navigation tree.
  useEffect(() => {
    if (error) throw error;
  }, [error]);

  useEffect(() => {
    if (loaded) {
      SplashScreen.hideAsync();
    }
  }, [loaded]);

  if (!loaded) {
    return null;
  }
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <Stack>
          <Stack.Screen
            name="index"
            options={{
              title: "Home",
            }}
          />
          <Stack.Screen
            name="[missing]"
            options={{
              title: "404",
            }}
          />
          <Stack.Screen
            name="(tabs)"
            options={{
              headerShown: false,
            }}
          />
          <Stack.Screen
            name="order/index"
            options={{
              headerShown: false,
            }}
          />
          <Stack.Screen
            name="search/searchpage"
            options={{
              headerShown: false,
            }}
          />
        </Stack>
      </PersistGate>
    </Provider>
  );
}

因此,当我尝试运行

saveNotificationResponse()
时,我收到此错误,如何解决此问题并仍将我的回复保存到商店?谢谢

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

正如您所说,触发 useDispatch 的 useEffect 位于您的减速器包装器之外。 您必须将 useEffect 放置在

<PersistGate/>
内的某个位置。

例如,您可以创建一个组件

HandlePushNotification
来包装您的堆栈
<Stack>

类似这样的事情:

export const HandlePushNotification = ({ children }) => {
  function saveNotificationResponse() {
    const dispatcher = useDispatch();
    const subscription = Notifications.addNotificationResponseReceivedListener(
      (response) => {
        console.log(response.notification.request.content.data);
        dispatcher(addMessage(response.notification.request.content.data));
      }
    );

    return () => {
      subscription.remove();
    };
  }
  useEffect(() => {
    saveNotificationResponse();
  }, []);

  return <>{children}</>;
};

在你的初始组件中:

return (
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <HandlePushNotification>
        <Stack>{/* {your code here} */}</Stack>
      </HandlePushNotification>
    </PersistGate>
  </Provider>
);
© www.soinside.com 2019 - 2024. All rights reserved.