Issue
I'm working on a project in NextJS for the first time, and I'm wondering what the right way to handle dynamic routing is.
I have a http://localhost:3000/trips
route which displays a page with list of cards, each of which represent a "trip":
When I tap on one of these cards, I want to navigate to a dynamic page for that route such as http://localhost:3000/trips/0b68a50a-8377-4720-94b4-fabdabc12da1
This is my folder structure:
As you can see, I already have the dynamic routes set up and it is working.
TripCard is the card component. TripComponent is a grid of TripCards. trips/index.tsx contains the TripsComponent (and other UI).
Currently I'm handling the dynamic route in TripCard as:
import { Trip } from './Models'
import { useRouter } from 'next/router'
const TripCard = ({ trip }: { trip: Trip }) => {
const router = useRouter()
return (
<div className="card bg-base-100 shadow-xl hover:bg-gray-100 active:bg-gray-300">
<div className="card-body" onClick={() => router.push('/trips/' + trip.id)}>
<h2 className="card-title">{trip.name}</h2>
<p>This is a trip!</p>
</div>
</div>
)
}
export default TripCard
And the dynamic page [tripId].tsx looks like:
import { NextPage } from 'next'
import { useRouter } from 'next/router'
const TripPage: NextPage = () => {
const router = useRouter()
const tripId = router.query.tripId
return (
<div>
<h1>This is {tripId}</h1>
</div>
)
}
export default TripPage
And TripsComponent.tsx:
import { Trip } from './Models'
import TripCard from './TripCard'
const TripsComponent = ({ trips }: { trips: Trip[] }) => {
return (
<div>
<div className="grid grid-cols-4 gap-4">
{trips.map((trip: Trip) => (
<div>
<TripCard trip={trip}></TripCard>
</div>
))}
</div>
</div>
)
}
export default TripsComponent
And trips/index.tsx:
import axios from 'axios'
import { GetStaticProps, InferGetStaticPropsType, NextPage } from 'next'
import { Trip } from '../../components/Models'
import TripsComponent from '../../components/TripsComponent'
const TripsPage: NextPage = (props: InferGetStaticPropsType<typeof getStaticProps>) => {
return (
<div className="m-9">
<h1 className="mt-9 text-3xl font-bold text-slate-800">Your Trips</h1>
<div className="justify-end">
<button className="btn btn-primary">Add Trip</button>
</div>
<div className="divider"></div>
<TripsComponent trips={props.data} />
</div>
)
}
export const getStaticProps: GetStaticProps = async () => {
// fetches data and passes to props
}
export default TripsPage
I guess my question is, what is the proper way to do routing like this where I have cards, and each card will go to a dynamic URL with an associated page? In TripCard I have a hardcoded router.push:
<div className="card-body" onClick={() => router.push('/trips/' + trip.id)}>
But that doesn't seem like the right way to handle this. For example, what if I want to use TripCard in another view and go to another route?
What's the best way to structure code that performs this function in NextJS?
Solution
Maybe you want to pass the url as props and use NextJs <Link/>
:
import { Trip } from './Models'
import { useRouter } from 'next/router'
import Link from 'next/link'
const TripCard = ({ trip, url }: { trip: Trip, url: string }) => {
const router = useRouter()
return (
<div className="card bg-base-100 shadow-xl hover:bg-gray-100 active:bg-gray-300">
<Link href={url} passHref>
<div className="card-body">
<h2 className="card-title">{trip.name}</h2>
<p>This is a trip!</p>
</div>
</Link>
</div>
)
}
export default TripCard
And then use the component like this:
<TripCard trip={trip} href={'/trips/' + trip.id}></TripCard>
Hope this help.
Answered By - blurk
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.