React Native菜谱应用搜索页无法跳转至详情页求助
React Native菜谱应用搜索结果跳转问题
我开发的React Native菜谱应用,API数据获取、搜索功能都正常,但搜索结果列表无法跳转至菜谱详情页,首页的跳转功能却完全正常。
List.js代码
import React from "react"; import { Text, View, FlatList, SafeAreaView } from "react-native"; import styles from "../styles/styles"; import RecipeCard from "./RecipeCard"; const List = ({ searchPhrase, setClicked, data, navigation, screen }) => { const formattedSearchPhrase = searchPhrase.trim().replace(/\s/g, "").toUpperCase(); const filteredData = data.filter((item) => { const formattedItemName = item.name?.trim().replace(/\s/g, "")?.toUpperCase(); const formattedItemDetails = item.details?.trim().replace(/\s/g, "")?.toUpperCase(); return formattedItemName?.includes(formattedSearchPhrase) || formattedItemDetails?.includes(formattedSearchPhrase); }); const openRecipePageFromList = (recipe) => { console.log('Navigating to screen:', recipe.screen); if (screen === 'SearchScreen') { navigation.navigate('SearchRecipePageScreen', { recipe: recipe }); } else if (screen === 'FavoritesScreen') { navigation.navigate('FavoritesRecipePageScreen', { recipe: recipe }); } }; const renderItem = ({ item }) => { const itemName = item.name?.trim(); const itemDetails = item.details?.trim(); if (!itemName && !itemDetails) { return null; } return ( <RecipeCard key={item.id} recipe={{ name: itemName, details: itemDetails, thumbnail_url: item.thumbnail_url }} screen={'SearchScreen'} onPress={() => openRecipePageFromList(item)} /> ); }; return ( <SafeAreaView style={styles.list__container}> <View onStartShouldSetResponder={() => { setClicked(false); }} > <FlatList data={filteredData} renderItem={renderItem} keyExtractor={(item) => item.id} extraData={searchPhrase} /> </View> </SafeAreaView> ); }; export default List;
RecipeCard.js代码
import React, { useState, useEffect } from 'react'; import { Text, View, Image, TouchableOpacity } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import styles from '../styles/styles'; import AsyncStorage from '@react-native-async-storage/async-storage'; export default function RecipeCard({ recipe, screen }) { const navigation = useNavigation(); const [isFavorite, setIsFavorite] = useState(false); useEffect(() => { const checkFavorite = async () => { try { const storedFavorites = await AsyncStorage.getItem('favoriteRecipes'); if (storedFavorites !== null) { const parsedFavorites = JSON.parse(storedFavorites); const found = parsedFavorites.some((favRecipe) => favRecipe.id === recipe.id); setIsFavorite(found); } } catch (e) { console.log(e); } }; checkFavorite(); }, [recipe.id]); const openRecipePage = () => { if (screen === 'HomeScreen') { navigation.navigate('HomeRecipePageScreen', { recipe: recipe }); } else if (screen === 'SearchScreen') { navigation.navigate('SearchRecipePageScreen', { recipe: recipe }); } else if (screen === 'FavoritesScreen') { navigation.navigate('FavoritesRecipePageScreen', { recipe: recipe }); } }; const handlePress = async () => { try { const storedFavorites = await AsyncStorage.getItem('favoriteRecipes'); let favoriteRecipes = []; if (storedFavorites !== null) { favoriteRecipes = JSON.parse(storedFavorites); } if (isFavorite) { const index = favoriteRecipes.findIndex((favRecipe) => favRecipe.id === recipe.id); if (index > -1) { favoriteRecipes.splice(index, 1); } } else { favoriteRecipes.push(recipe); } setIsFavorite(!isFavorite); await AsyncStorage.setItem('favoriteRecipes', JSON.stringify(favoriteRecipes)); } catch (e) { console.log(e); } }; return ( <View> <TouchableOpacity onPress={openRecipePage}> <View style={styles.recipeCardContainer}> <View style={styles.imageContainer}> <Image style={styles.image} source={{ uri: recipe.thumbnail_url }} /> <TouchableOpacity onPress={handlePress}> <Icon name={isFavorite ? 'heart' : 'heart-outline'} size={24} color={isFavorite ? 'red' : 'black'} style={styles.heartIcon} /> </TouchableOpacity> </View> <Text style={styles.recipeCardTextFrontPage}>{recipe.name}</Text> </View> </TouchableOpacity> </View> ); }
问题定位与修复方案
核心问题
- 传递的Recipe对象缺失关键属性:在List.js的
renderItem中,你手动拼接的recipe对象只包含name、details、thumbnail_url,缺少id。这会导致RecipeCard中依赖id的收藏判断失效,同时传递给详情页的菜谱数据不完整,可能引发跳转逻辑异常。 - 冗余的跳转函数未被使用:List.js中定义了
openRecipePageFromList并传递给RecipeCard的onPress属性,但RecipeCard内部并未调用该props,而是使用自身的openRecipePage函数,导致这个自定义跳转逻辑完全无效。
修复步骤
修正List.js中RecipeCard的recipe传递
直接传递完整的item对象(或至少包含所有必要属性),不要手动截断:return ( <RecipeCard key={item.id} recipe={item} // 传递完整的item,保留所有属性 screen={'SearchScreen'} /> );若担心冗余属性,可解构出需要的字段并保留id:
const { id, name, details, thumbnail_url } = item; return ( <RecipeCard key={id} recipe={{ id, name: name?.trim(), details: details?.trim(), thumbnail_url }} screen={'SearchScreen'} /> );修复RecipeCard的事件冒泡问题
爱心按钮嵌套在跳转卡片的TouchableOpacity中,点击爱心时会触发外层的跳转逻辑,需添加事件阻止:<TouchableOpacity onPress={(e) => { e.stopPropagation(); // 阻止事件冒泡到外层卡片 handlePress(); }}>验证导航栈配置
确认SearchRecipePageScreen已正确注册到导航栈中,且能正常接收route.params.recipe参数。
内容的提问来源于stack exchange,提问作者Krista
相关产品推荐
相关产品推荐

