typescript - Trecerea datelor dintr-un component către fișierul de layout prin expo-router
Vreau să transmit o proprietate (accountInfo) de la un component la fișierul de layout al aplicației. Componenta care are accountInfo este rutată dinamic, adică app/[accId]/index.tsx. Am diferite layouturi pentru diferite rute în fișierul rădăcină _layout.tsx.
_layout.tsx:
import { ErrorBoundaryProps, Stack, useNavigation } from "expo-router";
import CustomHeader from "@/Components/CustomHeader";
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
import Colors from "../constants/Colors";
import { TouchableOpacity, View, StyleSheet, Text, Linking } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { SvgUri } from "react-native-svg";
export const unstable_settings = {
// Ensure that reloading on `/modal` keeps a back button present.
initialRouteName: "index",
};
export default function RootLayoutNav() {
const navigation = useNavigation();
const handleEmailPress = () => {
const email = '[email ' //TODO: add providers actual data
Linking.openURL(`mailto:${email}`);
}
const handlePhonePress = () => {
const phoneNumber = '1234567890';
Linking.openURL(`tel:${phoneNumber}`);
};
const handleWebsitePress = () => {
const websiteUrl = 'https://sample.com/';
Linking.openURL(websiteUrl);
};
return (
<BottomSheetModalProvider>
<Stack>
<Stack.Screen
name="index"
options={{
header: () => <CustomHeader />,
}}
/>
<Stack.Screen
name="[acctId]/index"
options={{
headerTitle: "",
headerShadowVisible: false,
headerStyle: {
backgroundColor: Colors.lightGrey,
},
headerLeft: () => (
<TouchableOpacity
onPress={() => {
navigation.goBack();
}}
>
<Ionicons
name="close-outline"
size={28}
color={Colors.primary}
/>
</TouchableOpacity>
),
headerRight: (params) => {
return (
<TouchableOpacity style={{ flexDirection: 'row', marginRight: 15 }}>
<TouchableOpacity onPress={handleEmailPress}>
<Ionicons
name="mail-outline"
size={28}
color={Colors.primary}
paddingLeft={12}
/>
</TouchableOpacity>
<TouchableOpacity onPress={handlePhonePress}>
<Ionicons
name="ios-call-outline"
size={26}
color={Colors.primary}
paddingLeft={12}
/>
</TouchableOpacity>
<TouchableOpacity onPress={handleWebsitePress}>
<Ionicons
name="ios-globe-outline"
size={28}
color={Colors.primary}
paddingLeft={12}
/>
</TouchableOpacity>
</TouchableOpacity>
)
}
}}
/>
... other layout Screens
index.tsx: (app/accId/index.tsx)
import { Link, useLocalSearchParams, useNavigation } from "expo-router";
import React, { useEffect, useRef, useState } from "react";
import {
Image,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from "react-native-reanimated";
import { SafeAreaView } from "react-native-safe-area-context";
import startCase from "lodash/startCase";
import Stripe from "stripe";
import ParallaxScrollView from "@/Components/ParallaxScrollView";
import Colors from "@/constants/Colors";
import { ProductWithPrice, UnitLabel } from "@/types";
const ProviderComponent = (props: any) => {
const { acctId } = useLocalSearchParams();
const [activeIndex, setActiveIndex] = useState(0);
> const [accountInfo, setAccountInfo] = useState<Stripe.Account | null>(null);
const [isAccountInfoLoading, setIsAccountInfoLoading] = useState(true);
const [isAccountInfoError, setIsAccountInfoError] = useState(false);
const [isProductsInfoError, setIsProductsInfoError] = useState(false);
const { getAccountById, getProductsByAccountId } = useAppStore();
const navigation = useNavigation()
const categories = Object.keys(UnitLabel);
// Fetch Account Information
useEffect(() => {
getAccountById(acctId as string)
.then((data) => {
setAccountInfo(data);
})
.catch((error) => {
errorHandler(error);
setIsAccountInfoError(true);
})
.finally(() => {
setIsAccountInfoLoading(false);
});
}, [acctId]);
...
Aș putea implementa redux sau orice bibliotecă de gestionare a stării pentru asta, dar cred că ar fi exagerat pentru acest caz și ar face aplicația să se încarce mai greu. Există vreo altă modalitate mai eficientă de a gestiona acest lucru?