Как мне передать параметр id для перехода к компоненту details?

#node.js #react-native #api #express #fetch

#node.js #react-native #API #выразить #выборка

Вопрос:

Я пытаюсь перейти к ProductDetailsScreen.js и посмотреть подробную информацию об уникальном продукте, и в настоящее время я использую идентификатор параметра в методе рендеринга, чтобы перейти к уникальному продукту. Но, к сожалению, я получаю сообщение об ошибке: TypeError: не удается прочитать свойство ‘params’ undefined. Кто-нибудь может сказать мне, как это сделать правильно, или если у кого-нибудь есть правильный способ сделать это, я буду признателен. Вот ниже то, что я пытаюсь сделать:

AppNavigator.js:

 import * as React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import HomeScreen from "../screens/HomeScreen";
import ProductsScreen from "../screens/ProductsScreen";
import ProductDetailsScreen from "../screens/ProductDetailsScreen";

const Stack = createStackNavigator();

function MainStackNavigator() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Products" component={ProductsScreen} />
        <Stack.Screen name="Details" component={ProductDetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default MainStackNavigator;
  

productDetailScreen.js:

 function ProductDetailsScreen(props) {
  const [products, setProducts] = useState([]);
  const id = props.match.params.id;
  useEffect(() => {
    axios
      .get(`http://localhost:3000/api/products/id=${id}`)
      .then((res) => {
        setProducts(res.data.response);
      })
      .catch((err) => {
        console.error(err);
      });
  }, []);

  const dispatch = useDispatch();
  const addItemToCart = (item) =>
    dispatch({ type: ADD_TO_CART, payload: item });
  return (
    <View style={styles.container}>
      <View style={styles.shoppingCartContainer}>
        <View style={styles.shoppingCart}>
          <ShoppingCartIcon />
        </View>
      </View>
      <View>
        <FlatList
          data={products}
          keyExtractor={(item) => item.id.toString()}
          ItemSeparatorComponent={() => Separator()}
          renderItem={({ item, index }) => (
            <View style={styles.productItemContainer}>
              <Image
                source={require(`../../assets/images/${index   1}.jpg`)}
                style={styles.thumbnail}
              />

              <View style={styles.productItemMetaContainer}>
                <Text style={styles.row} numberOfLines={1}>
                  {item.id}
                </Text>
                <Text style={styles.row}>{item.name}</Text>

                <Text style={styles.row}> {item.categories}</Text>
                <Text style={styles.row}> {item.genders}</Text>
                <Text style={styles.row}> {item.brands}</Text>
                <Text style={styles.price}>$ {item.price}</Text>
                <View style={styles.buttonContainer}>
                  <TouchableOpacity
                    onPress={() => addItemToCart(item)}
                    style={styles.button}
                  >
                    <Text style={styles.buttonText}>Add to Cart  </Text>
                  </TouchableOpacity>
                </View>
              </View>
            </View>
          )}
        />
      </View>
    </View>
  );
}
  

ProductsScreen.js:

 function ProductsScreen() {
  const navigation = useNavigation();
  const [products, setProducts] = useState([]);

  useEffect(() => {
    axios
      .get('http://localhost:3000/product/')
      .then((res) => {
        setProducts(res.data.response);
      })
      .catch((err) => {
        console.error(err);
      });
  }, []);

  const dispatch = useDispatch();
  const addItemToCart = (item) =>
    dispatch({ type: ADD_TO_CART, payload: item });
  return (
    <View style={styles.container}>
      <View style={styles.shoppingCartContainer}>
        <View style={styles.shoppingCart}>
          <ShoppingCartIcon />
        </View>
      </View>
      <View>
        <FlatList
          data={products}
          keyExtractor={(item) => item.id.toString()}
          ItemSeparatorComponent={() => Separator()}
          renderItem={({ item, index }) => (
            <View style={styles.productItemContainer}>
              <Image
                source={require(`../../assets/images/${index   11}.jpg`)}
                style={styles.thumbnail}
              />

              <View style={styles.productItemMetaContainer}>
                <TouchableOpacity onPress={() => navigation.push("Details")}>
                  <Text style={styles.row} numberOfLines={1}>
                    {item.id}
                  </Text>
                </TouchableOpacity>
                <Text style={styles.row}>{item.name}</Text>

                <Text style={styles.row}> {item.categories}</Text>
                <Text style={styles.row}> {item.genders}</Text>
                <Text style={styles.row}> {item.brands}</Text>
                <Text style={styles.price}>$ {item.price}</Text>
                <View style={styles.buttonContainer}>
                  <TouchableOpacity
                    onPress={() => addItemToCart(item)}
                    style={styles.button}
                  >
                    <Text style={styles.buttonText}>Add to Cart  </Text>
                  </TouchableOpacity>
                </View>
              </View>
            </View>
          )}
        />
      </View>
    </View>
  );
}
  

Комментарии:

1. Как осуществляется навигация? и можем ли мы увидеть ваш стек?

2. Привет @Guruparan Giritharan, спасибо за ваш ответ, я только что обновил свой пост, и вы можете посмотреть.

Ответ №1:

Вы должны использовать функцию навигации, как показано ниже

 <TouchableOpacity onPress={() => navigation.navigate("Details",{id:1})}>
  

Вы также можете сделать

 <TouchableOpacity onPress={() => navigation.push("Details",{id:1})}>
  

Разница в том, что push добавит новые экраны, а navigate вернется, если экран уже находится в стеке.

Комментарии:

1. он все еще жалуется на ошибку в этой строке: const id = props.match.params.id ; , может быть, я сделаю там что-нибудь еще.

2. Это должно быть props.route.params.id

3. Да, спасибо, это сработало. Но еще одна проблема заключается в том, что я поставил значение параметра равным 1, и, конечно, любые элементы, на которые я нажимаю, переходят к элементу со значением, равным 1. Я хочу, чтобы при нажатии на любой элемент для перехода к нему были какие-либо советы о том, как я могу изменить значение id? Спасибо.

Ответ №2:

для передачи параметров используйте navigation.navigate("SCREEN_NAME", {YOUR_PARAM: "PARAM_VALUE"})

и для получения параметра на другом экране используйте this.props.route.params.YOUR_PARAM

Комментарии:

1. спасибо, это сработало. Но еще одна проблема заключается в том, что я поставил значение параметра равным 1, и, конечно, любые элементы, на которые я нажимаю, переходят к элементу со значением, равным 1. Я хочу, чтобы при нажатии на любой элемент для перехода к нему были какие-либо советы о том, как я могу изменить значение id? Спасибо

2. @saygas извините, я не понял вашу точную проблему, но, насколько я понимаю, навигация приведет вас только к экрану, который вы упомянули в `navigation.navigate (‘screen_name’)’

3. Проблема в том, что я назначил 1 в качестве значения параметра (navigation.navigate(«Details», {id: 1})) и у меня есть 15 продуктов. В этом случае при нажатии даже на другой номер продукта, кроме 1, я снова перехожу к номеру продукта 1. Что мне нужно, так это номер продукта, на который я нажимаю, я должен перейти к этому продукту. На этот раз я не очень хорошо это объясняю.

4. Не имеет значения, что вы передаете в параметрах, это перенаправит вас на экран, который вы упомянули в нем, здесь вы упомянули экран «Подробности», поэтому он перенаправит вас на экран Detail независимо от того, что вы передаете в параметре (1 или 2 или 3)