我正在构建一个博览会应用程序,并使用
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()
时,我收到此错误,如何解决此问题并仍将我的回复保存到商店?谢谢
正如您所说,触发 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>
);