Reputation: 25
I'm new to react-router v6
I have 4 components, App, CardList, Card and CardInfo. There is data (an array of objects, each object represents a movie) coming from an API that gets saved in App.js with useState hook.
Within CardList, I use map to iterate over the array to generate a bunch of Card components and passing in data via props.
What I want now is to be able to click on any Card component and for it to navigate to a different route, e.g. localhost:3000/1
(for Card with the id of 1), localhost:3000/2
(for Card with the id of 2) etc. and within each route that corresponds to the Card id, there would be a box/modal (CardInfo.js
) component with further information about the movie.
I'm trying to accomplish this with react-router-dom
(version 6).
It looks like within the CardList.js
or Card.js
component you would need to create links (<Link>
) and routes (<Route>
) (both which are equal to the number of movies in the data) on the fly with the .map function and wrapping the Card component in <Link>
and <Route>
tags. Something like
{items.map(movie => (
<Route path="/:id" element={<Card items={movies} />} exact>
<Link to={`/${movie.id}`}>
<Card
key={movie.id}
id={movie.id}
name={movie.name}
description={movie.description}
img={movie.image_url}
/>
</Link>
</Route>
))}
Obviously that doesn't work.
App.js:
import './App.css';
import CardList from './features/Card/CardList';
import CardInfo from './features/Card/CardInfo';
import { useState, useEffect } from "react";
import { BrowserRouter, Route, Routes } from 'react-router-dom';
function App() {
const [movies, setMovies] = useState([]);
useEffect(() => {
const getData = fetch('https://api.com/movies')
.then(data => data.json())
.then(items => { setMovies(items) })
}, [])
return (
<BrowserRouter>
<Routes>
<Route path="/:id" element={<CardInfo items={movies} />} exact></Route>
</Routes>
<CardList items={movies} />
</BrowserRouter>
);
}
export default App;
CardList.js:
import React from 'react'
import Card from './Card'
import "./CardList.css";
const CardList = ({ items }) => {
return (
<div className="cardList">
{items.map(movie => (
<Card
key={movie.id}
id={movie.id}
name={movie.name}
description={movie.description}
img={movie.image_url}
/>
))}
</div>
)
}
export default CardList
Card.js:
import React from 'react'
import "./Card.css";
import { Link } from 'react-router-dom';
function Card(props) {
return (
<Link to={`/${props.id}`}>
<div className="card">
<div>
<img src={props.img} />
<h2>{props.name}</h2>
</div>
</div>
</Link>
)
}
export default Card
CardInfo.js:
import React from 'react'
function CardInfo(props) {
return (
<div>
<p>{props.description}</p>
</div>
)
}
export default CardInfo
Upvotes: 2
Views: 1293
Reputation: 36
your code structure is correct. You just need to useLink
, you don't need en external Route
component for every card you map.
Here is a link for further information. Hope you find it helpful.
https://stackoverflow.com/a/57059249/17715977
Upvotes: 2