是onAuthChanged,因此当有人登录时它会呈现我的AppStack。现在,我需要在“成分”屏幕中从已登录人员那里获得用户ID。这个成分屏幕是Tabnavigator内部的Stacknavigator。因此,如何将数据从用户var传递到“成分”屏幕。
AuthNavigator文件:
import React, { useState, useEffect, createContext } from "react";
import firebase from "./firebase";
import AppStack from "./stacks/AppStack";
import AuthStack from "./stacks/AuthStack";
export const AuthContext = createContext(null);
export default function AuthNavigator() {
const [initializing, setInitializing] = useState(true);
const [user, setUser] = useState(true);
// Handle user state changes
async function onAuthStateChanged(result) {
setUser(result);
if (initializing) setInitializing(false);
console.log(user.uid)
var userDoc = await firebase.firestore().doc("users/" + user.uid).get();
if (!userDoc.exists) {
await userDoc.ref.set({
email: user.email,
uid: user.uid
})
}
}
useEffect(() => {
const authSubscriber = firebase
.auth()
.onAuthStateChanged(onAuthStateChanged);
// unsubscribe on unmount
return authSubscriber;
}, []);
if (initializing) {
return null;
}
return user ? (
<AuthContext.Provider value={user}>
<AppStack user={user} />
</AuthContext.Provider>
) : (
<AuthStack />
);
}
AppStack
import React, { lazy } from "react";
import News from "../screens/News";
import Favorites from "../screens/Favorites";
import NewRecipe from "../screens/NewRecipe";
import Ingredients from "../screens/Ingredients";
import Profile from "../screens/Profile";
import { NavigationContainer, DarkTheme } from "@react-navigation/native";
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { MaterialIcons } from "@expo/vector-icons";
import { createStackNavigator } from "@react-navigation/stack";
import { AuthContext } from "../AuthNavigator"
export default function AppStack() {
const Tab = createBottomTabNavigator();
const NewsStack = createStackNavigator();
const FavoritesStack = createStackNavigator();
const NewRecipeStack = createStackNavigator();
const IngredientsStack = createStackNavigator();
const ProfileStack = createStackNavigator();
function NewsNav() {
return (
<NewsStack.Navigator>
<NewsStack.Screen
name="News"
component={News}
options={{
headerTintColor: "#AD1457",
headerStyle: {
backgroundColor: "#171717",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</NewsStack.Navigator>
);
}
function FavoritesNav() {
return (
<FavoritesStack.Navigator>
<FavoritesStack.Screen
name="Favoriten"
component={Favorites}
options={{
headerTintColor: "#AD1457",
headerStyle: {
backgroundColor: "#171717",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</FavoritesStack.Navigator>
);
}
function NewRecipeNav() {
return (
<NewRecipeStack.Navigator mode="card">
<NewRecipeStack.Screen
name="Neue Rezepte"
component={NewRecipe}
options={{
headerTintColor: "#AD1457",
headerStyle: {
backgroundColor: "#171717",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</NewRecipeStack.Navigator>
);
}
function IngredientsNav(props) {
return (
<IngredientsStack.Navigator>
<IngredientsStack.Screen
name="Zutaten"
component={Ingredients}
options={{
headerTintColor: "#AD1457",
headerStyle: {
backgroundColor: "#171717",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</IngredientsStack.Navigator>
);
}
function ProfileNav() {
return (
<ProfileStack.Navigator >
<ProfileStack.Screen
name="Profil"
component={Profile}
options={{
headerTintColor: "#AD1457",
headerStyle: {
backgroundColor: "#171717",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</ProfileStack.Navigator >
);
}
return (
<NavigationContainer>
<AuthContext.Consumer value={user}>
<Tab.Navigator
tabBarOptions={{
style: {
backgroundColor: '#171717',
borderTopColor: '#121212'
},
inactiveTintColor: '#fff',
activeTintColor: '#AD1457',
}}
initialRouteName="News"
screenOptions={({ route }) => ({
tabBarIcon: ({ color }) => {
let iconName;
if (route.name == "News") {
iconName = "language";
} else if (route.name == "Favoriten") {
iconName = "star-border";
} else if (route.name == "Hinzufügen") {
iconName = "add-circle-outline";
} else if (route.name == "Zutaten") {
iconName = "shopping-cart";
} else if (route.name == "Profil") {
iconName = "person";
}
return (
<MaterialIcons
name={iconName}
color={color}
size={25}
></MaterialIcons>
);
},
})}
>
<Tab.Screen name="News" component={NewsNav} />
<Tab.Screen name="Favoriten" component={FavoritesNav} />
<Tab.Screen name="Hinzufügen" component={NewRecipeNav} />
<Tab.Screen name="Zutaten" component={IngredientsNav} />
<Tab.Screen name="Profil" component={ProfileNav} />
</Tab.Navigator>
</AuthContext.Consumer>
</NavigationContainer >
);
}
成分屏幕文件:
import React, { useState } from "react";
import { View, Text, StyleSheet, TextInput, ImageBackground, ActivityIndicator } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { FlatList, TouchableOpacity } from "react-native-gesture-handler";
import { AntDesign, Ionicons, Feather } from '@expo/vector-icons';
import firebase from "../firebase"
import { user } from '../AuthNavigator'
export default function Ingredients(props) {
const [isLoading, setIsLoading] = useState(false);
const ingredientsList = [
]
const [userIngredientsList, setUserIngredientsList] = useState(ingredientsList);
function handleRemoveItem(id, label) {
const newList = userIngredientsList.filter((item) => item.id !== id);
setUserIngredientsList(newList);
window.alert("Die Zutat " + (label) + " wurde gelöscht")
}
var appId = "20b96f8f",
appKey = "aebde7ed85b4aec1f50d3cbe4ff4f165";
async function fetchIngredient(searchValue) {
setIsLoading(true);
var request = new XMLHttpRequest();
request.open("GET", "https://api.edamam.com/api/food-database/v2/parser?app_id=" + appId + "&app_key=" + appKey + "&ingr=" + searchValue);
request.addEventListener('load', function (event) {
if (request.status >= 200 && request.status < 300) {
var food = JSON.parse(request.responseText).parsed[0].food;
console.log(user.uid)
var newItem = {
id: food.foodId,
label: searchValue,
image: food.image,
amount: 1
};
var found = false
userIngredientsList.forEach((item, index) => {
if (item.id == newItem.id) {
newItem.amount = item.amount + 1
userIngredientsList.splice(index, 1)
}
})
setUserIngredientsList(ingredientsList => [newItem, ...ingredientsList]);
setIsLoading(false);
setSearchValue('');
firebase.firestore().doc("ingredients/" + props.user.uid).set({
ingredients: userIngredientsList
})
}
else {
setIsLoading(false);
window.alert('Gibt es nicht')
}
});
request.send();
}
const renderItem = ({ item }) => (
<View style={styles.item} >
<View>
<ImageBackground source={{ uri: item.image }}
style={styles.itemBackground}
imageStyle={{ borderTopRightRadius: 18, borderBottomRightRadius: 18, opacity: 0.4 }}
resizeMode="cover">
<TouchableOpacity onPress={() => handleRemoveItem(item.id, item.label)}>
<AntDesign style={styles.iconDelete} name="delete" size={30} color="black" />
</TouchableOpacity>
</ImageBackground >
</View>
<View style={styles.itemInfo}>
<Text style={styles.itemTitle}>{item.title}</Text>
<Feather style={styles.iconTime} name="clock" size={30} color='#fff' />
<Text style={styles.itemCookingTime}>~ {item.time} min</Text>
<Text style={{ color: '#fff' }}>{item.amount} </Text>
</View>
</View >
)
const [searchValue, setSearchValue] = useState('');
return (
<View style={styles.container}>
<View style={styles.searchBar}>
<View style={{ alignSelf: "flex-end", marginTop: 8, marginRight: 30 }}>
<TouchableOpacity onPress={async () => await fetchIngredient(searchValue)}>
{!isLoading && <Ionicons name="md-add" size={32} color="#fff" />}
</TouchableOpacity>
{isLoading && <ActivityIndicator style={styles.loading} color='#AD1457' />}
</View>
{!isLoading && <TextInput style={{
alignSelf: "flex-start", marginLeft: 25, marginTop: -30, fontSize: 20, color: '#fff', width: 200
}} placeholder="Suche" placeholderTextColor='#fff' value={searchValue} onChangeText={(searchValue) => setSearchValue(searchValue)}></TextInput>}
</View>
<FlatList
data={userIngredientsList}
renderItem={renderItem}
keyExtractor={(item) => item.id}>
</FlatList>
</View >
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#121212",
},
item: {
flex: 1,
width: 350,
height: 200,
marginTop: 50,
alignSelf: "center",
borderWidth: 2,
borderRadius: 20,
borderColor: '#AD1457'
},
itemBackground: {
width: 174,
height: 196,
alignSelf: "flex-end",
backgroundColor: 'rgba(255,255,255,0.2)',
borderTopRightRadius: 18,
borderBottomRightRadius: 18
},
itemInfo: {
marginTop: -174,
width: 174,
height: 196,
alignSelf: "flex-start",
borderTopRightRadius: 18,
borderBottomRightRadius: 18
},
itemTitle: {
color: '#fff',
fontSize: 18,
alignSelf: "flex-start",
marginLeft: 35
},
iconTime: {
alignSelf: "flex-start",
marginLeft: 35,
marginTop: 75
},
itemCookingTime: {
marginLeft: 80,
fontSize: 18,
color: '#fff',
marginTop: -30
},
iconDelete: {
alignSelf: "flex-end",
marginRight: 25,
marginTop: 25,
color: '#fff'
},
checkCircle: {
alignSelf: "flex-end",
marginRight: 25,
marginTop: 85,
color: "#00FF44"
},
searchBar: {
backgroundColor: '#313131',
width: 325,
height: 50,
borderRadius: 25,
color: '#fff',
fontSize: 20,
marginTop: 25
},
loading: {
alignSelf: "flex-end",
marginTop: 8,
}
});
答案 0 :(得分:0)
我只用了useContext(AuthContext);