React详情页无法根据路由参数匹配电视节目数据问题求助
Let's break down what's going wrong and get your detail page working properly.
The Core Problem
Your main issue is how you're handling route parameters. When you run const b = JSON.stringify(params);, you're converting the entire params object (like { _id: "abc123" }) into a JSON string like "{"_id":"abc123"}". But your show objects have an _id field that's just the plain string ID (e.g., "abc123"), so comparing a._id === b will never match—you're comparing a plain string to a stringified object.
Additional Small Fixes Needed
- You tried rendering
a.titlein your map, but your state and props usename(check your initial state:{name:'', ...}and component props{name, info, ...})—that's a typo that would break the title display. - Your initial
showsstate has a single empty object in an array, which might cause weird rendering before your fetch completes. Starting with an empty array is cleaner. - You don't need to import the
Homecomponent here—this detail page should operate independently.
Corrected DetailPage Code
import React, { useState, useEffect } from 'react' import { useParams } from 'react-router-dom' import './detailpage.css' function DetailPage() { // Start with empty array instead of a single placeholder object const [shows, setShows] = useState([]) // Extract the _id directly from params (no need to stringify the whole object) const { _id: showId } = useParams(); useEffect(() => { fetch("/home") .then(res => { // Add basic error handling for failed requests if (!res.ok) throw new Error('Failed to fetch show data') return res.json() }) .then(jsonRes => setShows(jsonRes)) .catch(err => console.error('Error loading data:', err)) }, []) // Use find() instead of filter() since we only expect one matching show (IDs are unique) const matchedShow = shows.find(a => a._id === showId) // Show loading state while data fetches or if no match is found if (!matchedShow) { return <div>Loading show details...</div> } return ( <div> <div className='container'> <img className='showImg' src={matchedShow.poster} alt={matchedShow.name}></img> <h2 className='showTitle'>{matchedShow.name}</h2> {/* Fixed typo from title to name */} <h3>{matchedShow.genre}</h3> <p className='showInfo'>{matchedShow.info} </p> </div> <h2>{matchedShow.episodeNumber}</h2> <h2>{matchedShow.info}</h2> </div> ) } export default DetailPage
Key Changes Explained
- Param Handling: We destructure
_iddirectly fromuseParams()to get the plain string ID we need for matching. - Filtering: Switched to
find()instead offilter()because we only need one matching show (IDs should be unique). This gives us a single object instead of an array, simplifying rendering. - Loading State: Added a check for
!matchedShowto display a loading message while data loads, or if no matching show exists. - Typo Fix: Changed
a.titletoa.nameto align with your data structure. - Error Handling: Added basic error catching to debug failed API requests.
Quick Route Check
Make sure your router is set up correctly to pass the _id parameter, like:
<Route path="/detail/:_id" element={<DetailPage />} />
And when linking from the Home page, pass the correct ID in the URL:
<Link to={`/detail/${show._id}`}> <img src={show.poster} alt={show.name} /> </Link>
This should get your detail page displaying the correct show when you click a program image from Home!
内容的提问来源于stack exchange,提问作者elf

