#javascript #reactjs #react-native #expo #react-navigation
Вопрос:
Всякий раз, когда я нахожусь в History.js и я нажимаю на один из списков товаров, чтобы перейти на другую страницу, которая должна открыть новую страницу для более подробного описания и иметь возможность связаться с продавцом… итак, проблема, с которой я сталкиваюсь, заключается в следующем. всякий раз, когда я нажимаю на какой-либо элемент в History.js на этой странице ничего не происходит. но когда я открою Home.js затем я вижу, что он попал сюда в Home.js вместо того, чтобы History.js.. что я здесь упускаю?
Home.js
import React from "react"; import { View, Text, Button, SafeAreaView, TextInput, StatusBar, Platform, ScrollView, Image, StyleSheet, TouchableOpacity, } from "react-native"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import ProductsList from "../../components/productsList/ProductsList"; import Icon from "react-native-vector-icons/Ionicons"; import { fontSize } from "styled-system"; import Location from "../components/Location"; export default function Search({ navigation }) { return ( lt;SafeAreaView style={{ flex: 1 }}gt; lt;View style={{ flex: 1 }}gt; lt;View style={{ height: 80, backgroundColor: "white", borderBottomWidth: 1, borderBottomColor: "#dddddd", }} gt; lt;View style={{ flexDirection: "row", padding: 10, backgroundColor: "white", marginHorizontal: 20, shadowOffset: { width: 0, height: 0 }, shadowColor: "black", shadowOpacity: 0.2, borderRadius: 50, elevation: 1, }} gt; lt;Icon name="ios-search" size={20} style={{ marginRight: 10 }} /gt; lt;TextInput underlineColorAndroid="transparent" placeholder="City, airport, adrerss, or hotel" placeholderTextColor="grey" style={{ flex: 1, fontWeight: "700", backgroundColor: "white" }} /gt; lt;/Viewgt; lt;/Viewgt; lt;ScrollView horizontal={true} showsHorizontalScrollIndicator={false} scrollEventThrottle={16} gt; lt;View style={{ height: 175 }}gt; lt;Image source={require("../home/homepage.jpeg")} resizeMode="contain" /gt; lt;/Viewgt; lt;/ScrollViewgt; lt;ScrollView scrollEventThrottle={16}gt; lt;View style={{ flex: 1, backgroundColor: "white", paddingTop: 30, paddingRight: 40, justifyContent: "center", alignItems: "center", }} gt; lt;Text style={{ alignItems: "center", fontSize: 24, fontWeight: "700", paddingHorizontal: 25, marginLeft: 50, borderColor: "grey", height: 50, width: 230, shadowOpacity: 0.5, borderWidth: 0.5, paddingTop: 10, backgroundColor: "#f5bd1f", justifyContent: "center", }} gt; FIND YOUR RIDE lt;/Textgt; lt;View style={{ height: 130, marginTop: 20 }}gt; lt;ScrollView horizontal={true} showsHorizontalScrollIndicator={false} gt; lt;TouchableOpacitygt; lt;Location imageUri={require("../home/nicosia.jpg")} name="Nicosia" /gt; lt;/TouchableOpacitygt; lt;TouchableOpacitygt; lt;Location imageUri={require("../home/kyrenia.jpg")} name="Kyrenia" /gt; lt;/TouchableOpacitygt; lt;TouchableOpacitygt; lt;Location imageUri={require("../home/famagusta.jpg")} name="Famagusta" /gt; lt;/TouchableOpacitygt; lt;TouchableOpacitygt; lt;Location imageUri={require("../home/lefke.png")} name="Lefke" /gt; lt;/TouchableOpacitygt; lt;/ScrollViewgt; lt;/Viewgt; lt;Text style={{ flex: 1, fontWeight: "bold", fontSize: 24, alignItems: "center", color: "#f5bd1f", paddingLeft: 20, }} gt; / / / / / lt;/Textgt; lt;View style={{ marginTop: 40, paddingHorizontal: 20 }}gt; lt;Viewgt; lt;Text style={{ fontSize: 24, fontWeight: "700", paddingLeft: 40, }} gt; lt;Viewgt; lt;MaterialCommunityIcons name="face-agent" size={30} style={{ paddingLeft: 10, color: "#f5bd1f" }} /gt; lt;/Viewgt; 24/7 customer support lt;/Textgt; lt;Text style={{ paddingLeft: 80, marginTop: 20, marginBottom: 25 }} gt; { "Rest easy knowing that everyone in nthe Rent in cars community is screened, nand 24/7 customer support and nroadside assistant are just a tap away." } lt;/Textgt; lt;/Viewgt; lt;Viewgt; lt;Text style={{ fontSize: 24, fontWeight: "700", paddingLeft: 40, }} gt; lt;Viewgt; lt;MaterialCommunityIcons name="car" size={30} style={{ paddingLeft: 10, color: "#f5bd1f", marginTop: 20, }} /gt; lt;/Viewgt; Endless options lt;/Textgt; lt;Text style={{ paddingLeft: 80, marginTop: 20, marginBottom: 25 }} gt; { "Choose from hundreds of modelsnyou won't find anywhere else. Pick it nup or get it delivered where you nwant it." } lt;/Textgt; lt;/Viewgt; lt;Viewgt; lt;Text style={{ fontSize: 24, fontWeight: "700", paddingLeft: 40, }} gt; lt;Viewgt; lt;MaterialCommunityIcons name="security" size={30} style={{ paddingLeft: 10, color: "#f5bd1f" }} /gt; lt;/Viewgt; Drive confidently lt;/Textgt; lt;Text style={{ paddingLeft: 80, marginTop: 20, paddingBottom: 40 }} gt; { "Drive confidently with your choice nof protection plans - all plans ninclude varying levels of third party nliability insrurance from Liberty nMutual and physical damage nprotection from Rent in Car that capsnyour out of pocket responsibility for ndamage to your host's car during nyour trip." } lt;/Textgt; lt;/Viewgt; lt;Text style={{ fontWeight: "bold", fontSize: 24, alignItems: "center", color: "#f5bd1f", paddingLeft: 150, }} gt; / / / / / lt;/Textgt; lt;View style={{ marginTop: 30 }}gt;lt;/Viewgt; lt;/Viewgt; lt;/Viewgt; lt;/ScrollViewgt; lt;/Viewgt; lt;/SafeAreaViewgt; ); const styles = StyleSheet.create({ container: { flex: 1, alignItems: "center", justifyContent: "center", }, red: { color: "red", }, }); }
History.js
import moment from "moment"; import React, { useState } from "react"; import Firebase from "../../config/firebase"; import ProductsList from "../../components/productsList/ProductsList"; import { FlatList, Text, View, Image, TouchableWithoutFeedback, TextInput, ActivityIndicator, } from "react-native"; import { Colors } from "../../staticValues/Colors"; import { Devicewidth, productCardWidth } from "../../staticValues/Dimensions"; import { useEffect } from "react"; import { styles } from "../../styles/authStyle"; import { FontAwesome5 } from "@expo/vector-icons"; import { I18n } from "../../helper/Multilanguage"; export default function HistoryList({ navigation }) { const [filtredList, setfiltredList] = useState([]); const [isFetching, setisFetching] = useState(false); const [allProduct, setallProduct] = useState([]); const [searchInput, setsearchInput] = useState(""); const [visible, setVisible] = React.useState(true); function onRefresh() { getAllProdcuts(); } function getAllProdcuts() { setisFetching(true); Firebase.firestore() .collection("Products") .get() .then((docRef) =gt; { var list = []; docRef.forEach((elm) =gt; { list.push(elm.data()); }); setfiltredList(list); setallProduct(list); setisFetching(false); }) .catch((error) =gt; { console.log({ error }); setisFetching(false); }); } useEffect(() =gt; { getAllProdcuts(); const willFocusSubscription = navigation.addListener("focus", () =gt; { getAllProdcuts(); }); return willFocusSubscription; }, []); return ( lt;View style={{ flex: 1, }} gt; lt;View style={{ width: "80%", backgroundColor: Colors.lightGray, borderRadius: 30, height: 45, marginBottom: 5, justifyContent: "center", padding: 20, alignSelf: "center", marginTop: 10, }} gt; lt;FontAwesome5 name={"search"} size={26} color={"black"} style={styles.inputIcon} /gt; lt;TextInput style={styles.loginpass} placeholder={I18n.t("searchProduct")} placeholderTextColor="#fff" onChangeText={(input) =gt; { setsearchInput(input); // filter list const SearchResult = allProduct.filter((product) =gt; product.title.toLowerCase().includes(input.toLocaleLowerCase()) ); setfiltredList(SearchResult); }} /gt; lt;/Viewgt; lt;View style={{ alignItems: "center", flex: 1, }} gt; lt;FlatList ListEmptyComponent={() =gt; { return ( lt;Viewgt; {!isFetching amp;amp; ( lt;Text style={{ textAlign: "center", color: Colors.accentColor, fontWeight: "bold", paddingVertical: 20, }} gt; {I18n.t("noProduct")} lt;/Textgt; )} lt;/Viewgt; ); }} onRefresh={() =gt; onRefresh()} refreshing={isFetching} keyExtractor={(item) =gt; item.image} numColumns={2} data={filtredList} renderItem={({ item }) =gt; { return ( lt;TouchableWithoutFeedback onPress={() =gt; { navigation.push("ProductDetails", { selectedProduct: item, }); }} gt; lt;View style={{ backgroundColor: "white", alignItems: "center", padding: 3, elevation: 4, borderRadius: 10, margin: 6, }} gt; lt;Viewgt; lt;Image source={{ uri: item.image }} style={{ height: productCardWidth, width: productCardWidth, borderRadius: 10, marginBottom: 5, zIndex: 1, }} /gt; lt;View style={{ alignItems: "center", justifyContent: "center", height: productCardWidth, width: productCardWidth, position: "absolute", backgroundColor: Colors.lightGray, borderRadius: 10, marginBottom: 5, zIndex: 0, }} gt; lt;ActivityIndicator color={Colors.accentColor} size={"small"} style={{ top: 10, right: 10, position: "absolute", }} /gt; lt;FontAwesome5 name={"image"} size={26} color={"black"} style={ { // position: "absolute", } } /gt; lt;/Viewgt; lt;/Viewgt; lt;Text style={{ color: Colors.dark, fontWeight: "bold", fontSize: 16, }} gt; {item.title.length gt; 12 ? item.title.slice(0, 12) "..." : item.title} lt;/Textgt; lt;Text style={{ fontWeight: "bold", }} gt; {item.price} {item.currency} lt;/Textgt; lt;/Viewgt; lt;/TouchableWithoutFeedbackgt; ); }} /gt; lt;/Viewgt; lt;/Viewgt; ); }
This is the HomeStack
import React from "react"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import Home from "../screens/home/Home"; import Profile from "../screens/profile/Profile"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import Messages from "../screens/messages/Messages"; import ProductStack from "./ProductStack"; import { Colors } from "../staticValues/Colors"; import SellProductForm from "../components/sellProduct/SellProductForm"; import History from "../components/history/History"; import ChatStack from "./ChatStack"; import AllMessages from "../screens/messages/AllMessages"; import { I18n } from "../helper/Multilanguage"; export default function HomeStack() { const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); return ( lt;Tab.Navigator initialRouteName="Search" screenOptions={{ tabBarActiveTintColor: Colors.mainColor, tabBarActiveTintColor: Colors.mainColor, tabBarHideOnKeyboard: true, }} gt; lt;Tab.Screen name="ProductStack" component={ProductStack} options={{ headerShown: false, tabBarLabel: I18n.t("Search"), tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="magnify" color={color} size={size} /gt; ), }} /gt; lt;Tab.Screen name={I18n.t("myProducts")} component={History} options={{ tabBarLabel: I18n.t("Trips"), tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="road-variant" color={color} size={size} /gt; ), }} /gt; lt;Tab.Screen name="Messages" component={ChatStack} options={{ tabBarLabel: I18n.t("messages"), headerShown: false, tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="message-outline" color={color} size={size} /gt; ), }} /gt; lt;Tab.Screen name="SellProductForm" component={SellProductForm} options={{ tabBarLabel: I18n.t("Host"), title: "Host", tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="car" size={size} /gt; ), }} /gt; lt;Tab.Screen name={I18n.t("More")} component={Profile} options={{ tabBarLabel: I18n.t("More"), tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="dots-horizontal" color={color} size={size} /gt; ), }} /gt; lt;/Tab.Navigatorgt; ); }
This is the productStack
import { createNativeStackNavigator } from "@react-navigation/native-stack"; import React from "react"; import { I18n } from "../helper/Multilanguage"; import Home from "../screens/home/Home"; import ProductDetails from "../screens/product/ProductDetails"; export default function ProductStack() { const Stack = createNativeStackNavigator(); return ( lt;Stack.Navigatorgt; lt;Stack.Screen options={{ title: I18n.t("home"), }} name="Home" component={Home} /gt; lt;Stack.Screen options={{ title: I18n.t("productDetails"), }} name="ProductDetails" component={ProductDetails} /gt; lt;/Stack.Navigatorgt; ); }
это root.js
import React, { useState, useEffect } from "react"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import AuthStack from "./AuthStack"; import HomeStack from "./HomeStack"; import Firebase from "../config/firebase"; import { Text } from "react-native"; import { setCurrentUser } from "../staticValues/CurrentUser"; import Splach from "../components/Splach"; export default function Root() { const Stack = createNativeStackNavigator(); // Set an initializing state whilst Firebase connects const [initializing, setInitializing] = useState(true); const [user, setUser] = useState(); // Handle user state changes function onAuthStateChanged(curentUser) { setCurrentUser(curentUser); setUser(curentUser); if (initializing) setInitializing(false); } useEffect(() =gt; { const subscriber = Firebase.auth().onAuthStateChanged(onAuthStateChanged); return subscriber; // unsubscribe on unmount }, []); if (initializing) { return lt;Splach /gt;; } else { return ( lt;NavigationContainergt; {user ? ( lt;Stack.Navigator screenOptions={{ headerShown: false, }} gt; lt;Stack.Screen name="HomeStack" component={HomeStack} /gt; lt;/Stack.Navigatorgt; ) : ( lt;Stack.Navigator screenOptions={{ headerShown: false, }} gt; lt;Stack.Screen name="AuthStack" component={AuthStack} /gt; lt;/Stack.Navigatorgt; )} lt;/NavigationContainergt; ); } }
Комментарии:
1. Можете ли вы также поделиться routes.js файл(который содержит все навигации приложения)gt; Я считаю, что History.js и Home.js находятся в разных стопках и «ProductDetails.js» находится в Home.js стопка! Если вы поделитесь своими routes.js файл, я могу помочь вам решить эту проблему
2. спасибо, что ответили.. Я добавил файлы, пожалуйста, проверьте их
3. здравствуйте, у вас есть возможность взглянуть на него? @Гэвин Д’Мелло
4. Да, нашел вашу проблему. В настоящее время вы находитесь на другой вкладке/стеке, т. Е. в стеке истории, но файл, к которому вы обращаетесь, находится в пакете продуктов, поэтому, когда вы вызываете навигатор, он делает то, что должен, т. Е. Переходит на страницу ProductDetails, но поскольку он объявлен в пакете продуктов, обновление происходит там само. Я добавляю навигационное решение для вас в качестве ответа ниже. Пожалуйста, проверьте это, и если это работает, пожалуйста, поддержите его, а также этот комментарий, если это имеет смысл.
5. Я только что опубликовал решение. Пожалуйста, проверьте
Ответ №1:
Итак, проблема в вашем коде заключается в том, что в настоящее время вы находитесь на другой вкладке/стеке, т. Е. в стеке истории, но файл, к которому вы обращаетесь, находится в наборе продуктов, поэтому, когда вы вызываете навигатор, он делает то, что должен делать, т. Е. Перейдите на страницу ProductDetails, но поскольку он объявлен в наборе продуктов, обновление происходит там само.
Чтобы решить вашу проблему, необходимо выполнить следующие действия.
- Создайте сток истории, который будет содержать 2 экрана. Во — первых, это «History.js» а второе-это «ProductDetails.js». ПРИМЕЧАНИЕ: При объявлении/использовании класса в нескольких стеках(в вашем случае — «ProductDetails.js», вам нужно использовать/указать другое/уникальное имя для этого класса внутри стека
Пример:
lt;Stack.Screen name="UNIQUE NAME HERE" component={Original name of your Js file. Eg. "ProductDetails"} /gt;
- Вместо истории в вашей вкладке «Навигация» передайте только что созданный вами исторический стек(я создал для вас исторический стек ниже).
- В вашем History.js файл, если вы хотите перейти к экрану ProductDetails, используйте приведенный ниже код:
навигация.нажмите(«ProductDetailsHistoryTab», { Выбранный продукт: товар });
Хоумстэк
import React from "react"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import Home from "../screens/home/Home"; import Profile from "../screens/profile/Profile"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import Messages from "../screens/messages/Messages"; import ProductStack from "./ProductStack"; import { Colors } from "../staticValues/Colors"; import SellProductForm from "../components/sellProduct/SellProductForm"; import HistoryStack from "./HistoryStack"; import ChatStack from "./ChatStack"; import AllMessages from "../screens/messages/AllMessages"; import { I18n } from "../helper/Multilanguage"; export default function HomeStack() { const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); return ( lt;Tab.Navigator initialRouteName="Search" screenOptions={{ tabBarActiveTintColor: Colors.mainColor, tabBarActiveTintColor: Colors.mainColor, tabBarHideOnKeyboard: true, }} gt; lt;Tab.Screen name="ProductStack" component={ProductStack} options={{ headerShown: false, tabBarLabel: I18n.t("Search"), tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="magnify" color={color} size={size} /gt; ), }} /gt; lt;Tab.Screen name={I18n.t("myProducts")} //Replaced History class with a HistoryStack component={HistoryStack} options={{ tabBarLabel: I18n.t("Trips"), tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="road-variant" color={color} size={size} /gt; ), }} /gt; lt;Tab.Screen name="Messages" component={ChatStack} options={{ tabBarLabel: I18n.t("messages"), headerShown: false, tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="message-outline" color={color} size={size} /gt; ), }} /gt; lt;Tab.Screen name="SellProductForm" component={SellProductForm} options={{ tabBarLabel: I18n.t("Host"), title: "Host", tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="car" size={size} /gt; ), }} /gt; lt;Tab.Screen name={I18n.t("More")} component={Profile} options={{ tabBarLabel: I18n.t("More"), tabBarIcon: ({ color, size }) =gt; ( lt;MaterialCommunityIcons name="dots-horizontal" color={color} size={size} /gt; ), }} /gt; lt;/Tab.Navigatorgt; ); }
Исторический стек
import { createNativeStackNavigator } from "@react-navigation/native-stack"; import React from "react"; import { I18n } from "../helper/Multilanguage"; import History from "../components/history/History"; import ProductDetails from "../screens/product/ProductDetails"; export default function HistoryStack() { const Stack = createNativeStackNavigator(); return ( lt;Stack.Navigatorgt; lt;Stack.Screen options={{ title: I18n.t("home"), }} name="History" component={History} /gt; lt;Stack.Screen options={{ title: I18n.t("productDetails"), }} name="ProductDetailsHistoryTab" component={ProductDetails} /gt; lt;/Stack.Navigatorgt; ); }
А теперь о History.js
function onRefresh() { getAllProdcuts(); } function getAllProdcuts() { setisFetching(true); Firebase.firestore() .collection("Products") .get() .then((docRef) =gt; { var list = []; docRef.forEach((elm) =gt; { list.push(elm.data()); }); setfiltredList(list); setallProduct(list); setisFetching(false); }) .catch((error) =gt; { console.log({ error }); setisFetching(false); }); } useEffect(() =gt; { getAllProdcuts(); const willFocusSubscription = navigation.addListener("focus", () =gt; { getAllProdcuts(); }); return willFocusSubscription; }, []); return ( lt;View style={{ flex: 1, }} gt; lt;View style={{ width: "80%", backgroundColor: Colors.lightGray, borderRadius: 30, height: 45, marginBottom: 5, justifyContent: "center", padding: 20, alignSelf: "center", marginTop: 10, }} gt; lt;FontAwesome5 name={"search"} size={26} color={"black"} style={styles.inputIcon} /gt; lt;TextInput style={styles.loginpass} placeholder={I18n.t("searchProduct")} placeholderTextColor="#fff" onChangeText={(input) =gt; { setsearchInput(input); // filter list const SearchResult = allProduct.filter((product) =gt; product.title.toLowerCase().includes(input.toLocaleLowerCase()) ); setfiltredList(SearchResult); }} /gt; lt;/Viewgt; lt;View style={{ alignItems: "center", flex: 1, }} gt; lt;FlatList ListEmptyComponent={() =gt; { return ( lt;Viewgt; {!isFetching amp;amp; ( lt;Text style={{ textAlign: "center", color: Colors.accentColor, fontWeight: "bold", paddingVertical: 20, }} gt; {I18n.t("noProduct")} lt;/Textgt; )} lt;/Viewgt; ); }} onRefresh={() =gt; onRefresh()} refreshing={isFetching} keyExtractor={(item) =gt; item.image} numColumns={2} data={filtredList} renderItem={({ item }) =gt; { return ( lt;TouchableWithoutFeedback onPress={() =gt; { navigation.push("ProductDetailsHistoryTab", { selectedProduct: item, }); }} gt; lt;View style={{ backgroundColor: "white", alignItems: "center", padding: 3, elevation: 4, borderRadius: 10, margin: 6, }} gt; lt;Viewgt; lt;Image source={{ uri: item.image }} style={{ height: productCardWidth, width: productCardWidth, borderRadius: 10, marginBottom: 5, zIndex: 1, }} /gt; lt;View style={{ alignItems: "center", justifyContent: "center", height: productCardWidth, width: productCardWidth, position: "absolute", backgroundColor: Colors.lightGray, borderRadius: 10, marginBottom: 5, zIndex: 0, }} gt; lt;ActivityIndicator color={Colors.accentColor} size={"small"} style={{ top: 10, right: 10, position: "absolute", }} /gt; lt;FontAwesome5 name={"image"} size={26} color={"black"} style={ { // position: "absolute", } } /gt; lt;/Viewgt; lt;/Viewgt; lt;Text style={{ color: Colors.dark, fontWeight: "bold", fontSize: 16, }} gt; {item.title.length gt; 12 ? item.title.slice(0, 12) "..." : item.title} lt;/Textgt; lt;Text style={{ fontWeight: "bold", }} gt; {item.price} {item.currency} lt;/Textgt; lt;/Viewgt; lt;/TouchableWithoutFeedbackgt; ); }} /gt; lt;/Viewgt; lt;/Viewgt; ); }
Так и должно быть. Поддержите мое решение, если оно сработало для вас, или предложите вам идею исправить ваше решение.
Добавляйте комментарии, если у вас есть какие-либо вопросы по этому поводу. С удовольствием помогу!
Комментарии:
1. БОЛЬШОЕ ВАМ СПАСИБО !!! ЭТО СРАБОТАЛО
2. Добро пожаловать!