React中如何用CardData替换App状态并在ProjectDetailPage渲染数据
Hey there! Let's figure out how to make your project details show up in the ProjectDetailPage when clicking a card from ProjectCardContainer. Since you already have your CardData ready, we'll focus on managing state in the App component and passing data between components properly.
Step 1: Manage Selected Project State in App
First, we'll add state to your App component to track which project was clicked. This way, we can pass that selected project data down to ProjectDetailPage.
Here's how your updated App.tsx might look:
import React, { useState } from 'react'; import ProjectCardContainer from './ProjectCardContainer'; import ProjectDetailPage from './ProjectDetailPage'; import CardData from './CardData'; function App() { // State to hold the selected project data const [selectedProject, setSelectedProject] = useState<typeof CardData.cards[0] | null>(null); // Function to handle card clicks - passes the clicked project data up to App const handleCardClick = (project: typeof CardData.cards[0]) => { setSelectedProject(project); }; return ( <div className="App"> {/* Pass the click handler and card data to ProjectCardContainer */} <ProjectCardContainer cards={CardData.cards} onCardClick={handleCardClick} /> {/* Pass the selected project to ProjectDetailPage */} <ProjectDetailPage selectedProject={selectedProject} /> </div> ); } export default App;
Step 2: Update ProjectCardContainer to Trigger Click Handler
Next, modify your ProjectCardContainer (or the individual ProjectCard component inside it) to call the onCardClick function when the <h6> is clicked. Assuming you have a ProjectCard component, here's an example:
// Inside ProjectCard.tsx (or directly in ProjectCardContainer) import React from 'react'; type ProjectCardProps = { project: typeof import('./CardData').default['cards'][0]; onCardClick: (project: typeof import('./CardData').default['cards'][0]) => void; }; const ProjectCard = ({ project, onCardClick }: ProjectCardProps) => { return ( <div className="project-card"> {/* Make the h6 clickable and trigger the handler */} <h6 onClick={() => onCardClick(project)} style={{ cursor: 'pointer' }}> {project.projectName} </h6> {/* Rest of your card content (image, description, etc.) */} <img src={project.profileProjectImage} alt={project.projectName} /> <p>By {project.projectBy}</p> </div> ); }; export default ProjectCard;
And in ProjectCardContainer, map through the cards and pass each one to ProjectCard along with the click handler:
import React from 'react'; import ProjectCard from './ProjectCard'; type ProjectCardContainerProps = { cards: typeof import('./CardData').default['cards']; onCardClick: (project: typeof import('./CardData').default['cards'][0]) => void; }; const ProjectCardContainer = ({ cards, onCardClick }: ProjectCardContainerProps) => { return ( <div className="card-container"> {cards.map(project => ( <ProjectCard key={project.projectID} project={project} onCardClick={onCardClick} /> ))} </div> ); }; export default ProjectCardContainer;
Step 3: Display Selected Project in ProjectDetailPage
Finally, update ProjectDetailPage to receive the selectedProject prop and display its data as text:
import React from 'react'; type ProjectDetailPageProps = { selectedProject: typeof import('./CardData').default['cards'][0] | null; }; const ProjectDetailPage = ({ selectedProject }: ProjectDetailPageProps) => { if (!selectedProject) { return <p>Select a project to see details</p>; } return ( <div className="project-detail"> <h2>Project Details</h2> <p><strong>Project ID:</strong> {selectedProject.projectID}</p> <p><strong>Name:</strong> {selectedProject.projectName}</p> <p><strong>By:</strong> {selectedProject.projectBy}</p> <p><strong>Description:</strong> {selectedProject.projectDescrition}</p> <p><strong>Location:</strong> {selectedProject.projectLocation}</p> <img src={selectedProject.profileProjectImage} alt={selectedProject.projectName} /> </div> ); }; export default ProjectDetailPage;
Your CardData.tsx (for reference)
Just to keep things clear, here's your original CardData formatted properly:
const CardData = { "cards": [ { "projectID": "00001", "projectName": "One tent system", "profileProjectImage": "https://s3-sa-east-1.amazonaws.com/cdn.br.catarse/uploads/project/uploaded_image/72644/project_thumb_large_capinha.jpg", "projectBy": "Crua Outdoors", "projectDescrition": "Lightweight Hiking Tent + Insulated Cocoon + Air-Framed Living Space: Use individually or together for the ultimate outdoors experience", "projectLocation": " New York, NY" }, { "projectID": "00002", "projectName": "Two tent system", "profileProjectImage": "https://s3-sa-east-1.amazonaws.com/cdn.br.catarse/uploads/project/uploaded_image/72644/project_thumb_large_capinha.jpg", "projectBy": "Crua Outdoors", "projectDescrition": "Lightweight Hiking Tent + Insulated Cocoon + Air-Framed Living Space: Use individually or together for the ultimate outdoors experience", "projectLocation": " New York, NY" }, { "projectID": "00003", "projectName": "Three tent system", "profileProjectImage": "https://s3-sa-east-1.amazonaws.com/cdn.br.catarse/uploads/project/uploaded_image/72644/project_thumb_large_capinha.jpg", "projectBy": "Crua Outdoors", "projectDescrition": "Lightweight Hiking Tent + Insulated Cocoon + Air-Framed Living Space: Use individually or together for the ultimate outdoors experience", "projectLocation": " New York, NY" } ] }; export default CardData;
The key idea here is lifting state up to the common parent component (App), which allows you to share data between child components. When a card is clicked, we update the state in App, and that state is passed down to ProjectDetailPage to render the details.
内容的提问来源于stack exchange,提问作者amar ghodke

