简体   繁体   中英

Dynamic routing using graphQL in a Next.js app

I'm building a webpage that consumes the spaceX graphQL api, using apollo as a client. On the landing page I want to display a 'launches' card, that when clicked on, directs to a new page with details about that particular launch, as below:

index.js

import { ApolloClient, InMemoryCache, gql } from "@apollo/client"
import Link from 'next/link'

export const getStaticProps = async () => {

  const client = new ApolloClient({
    uri: 'https://api.spacex.land/graphql/',
    cache: new InMemoryCache()
  })

  const { data } = await client.query({
    query: gql`
      query GetLaunches {
        launchesPast(limit: 10) {
          id
          mission_name
          launch_date_local
          launch_site {
            site_name_long
          }
          links {
            article_link
            video_link
            mission_patch
          }
          rocket {
            rocket_name
          }
        }
      }
    `
  });

  return {
    props: {
      launches: data.launchesPast
    }
  }
}

export default function Home({ launches }) {

  return (
    <div>
      {launches.map(launch => {
        return(
          <Link href = {`/items/${launch.id}`} key = {launch.id}>
            <a>
              <p>{launch.mission_name}</p>
            </a>
          </Link>
        )
      })}
    </div>
  )
}

I've set up a new page items/[id].js to display information about individual launches, but this is where the confusion is. Using a standard REST api I'd simply use fetch , then append the id to the end of the url to retrieve the desired data. However I'm not sure how to do the equivalent in graphQL, using the getStaticPaths function. Any suggestions?

Here's items/[id]/js , where I'm trying to render the individual launch data:

import { ApolloClient, InMemoryCache, gql } from "@apollo/client"

export const getStaticPaths = async () => {

  const client = new ApolloClient({
    uri: "https://api.spacex.land/graphql/",
    cache: new InMemoryCache(),
  });

  const { data } = await client.query({
    query: gql`
      query GetLaunches {
        launchesPast(limit: 10) {
          id
        }
      }
    `,
  });

  const paths = data.map((launch) => {
    return {
      params: { id: launch.id.toString() },
    };
  });

  return {
      paths,
      fallback:false
  }

};

export const getStaticProps = async (context) => {
    const id = context.params.id
// not sure what to do here
}

const Items = () => {
    return ( 
        <div>
            this is items
        </div>
     );
}
 
export default Items;

for getStaticPaths

export const getStaticPaths = async () => {
  const { data } = await client.query({
    query: launchesPastQuery, // this will query the id only
  });
  return {     
    paths: data.CHANGE_THIS.map((param) => ({
      params: { id: param.id },
    })),
    fallback: false,
  };
};

CHANGE_THIS is the Query Type that follows data in the JSON response.

for getStaticProps

export const getStaticProps = async ({
  params,
}) => {
  const { data } = await client.query({
    query: GetLaunchPastByID ,
    variables: { LaunchID: params.id, idType: "UUID" }, // the idType is optional, and the LaunchID is what you'll use for querying by it*
  });

  return {
    props: {
      launchesPast: data.CHANGE_THIS,
    },
  };

The launchPastQueryByID is like:

const GetLaunchPastByID = gql`
  query LaunchPastByID($LaunchID: UUID!) { // UUID is id type
    CHANGE_THIS(id: $LaunchID) {
      id
      //...
    }
  }
`;

sorry for not giving you the correct queries, spacex.land is currently down.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM