Nextjs 中使用 getServerSideProps 进行动态路由

新手上路,请多包涵

我正在努力学习 nextjs。努力与 getServerSideProps 一起制定路由。

使用免费的 API,我在 DOM 上显示了一个国家列表。我想动态链接到一个国家,并为该特定国家获取和显示数据。

到目前为止,这是我的代码

const Country = props => (
  <Layout>
    <h1>{props.country.name}</h1>
    <span>{props.country.capital}</span>
  </Layout>
);
export async function getServerSideProps(context) {
  const { id } = context.query;
  const res = await fetch(`https://restcountries.eu/rest/v2/name/${id}`);
  const country = await res.json();

  console.log(`Fetched place: ${country.name}`);
  return { props: { country } };
}
export default Country;

   <div className='container'>
    <Head>
      <title>Countries List</title>
      <link rel='icon' href='/favicon.ico' />
    </Head>
    <Layout>
      <main>
        <h1>
          Countries{' '}
          <span role='img' aria-label='world emoji'>
            🌎
          </span>
        </h1>
        <ul>
          {countries.map(country => (
            <li key={country.name}>
              <Link href='/p/[id]' as={`/p/${country.name}`}>
                <a>{country.name}</a>
              </Link>
            </li>
          ))}
        </ul>
      </main>
    </Layout>
  </div>
);

export async function getServerSideProps() {
  // Call an external API endpoint to get posts.
  const res = await fetch('https://restcountries.eu/rest/v2/all');
  const countries = await res.json();

  // By returning { props: posts }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      countries,
    },
  };
}

export default Home;

URL 动态路由 ok。例如,当您单击阿富汗时,URL 显示 http://localhost:3000/p/Afghanistan

但是,我的国家/地区组件不显示任何内容,并且 undefined 打印到终端。

URL 示例和来自 URL 的响应: https://restcountries.eu/rest/v2/name/Afghanistan

 {
name: "Afghanistan"
}

如果是菜鸟问题,我们深表歉意。努力学习 nextjs

原文由 DGB 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.6k
2 个回答
export async function getServerSideProps(context) {
  const { id } = context.query;
  const res = await fetch(`https://restcountries.eu/rest/v2/name/${id}`);
  const country = await res.json();

  console.log(`Fetched place: ${country.name}`);
  return { props: { country } };
}

您正在从上面的函数返回一个嵌套对象

    { props: { country:country } }

所以这个道具将像这样附加到道具上:

       `props.props`

这是你应该如何实施

const Country = props => (
  <Layout>
    <h1>{props.props.country.name}</h1>
    <span>{props.props.country.capital}</span>
  </Layout>
);

更新

在 next.js 的早期版本中,我认为在版本 9 之后更新,我们没有使用 props 从服务器端函数返回。截至目前,正确的实施方式是

return {
    props: {
      countries,
    },
  };

Next.js 13 更新

在next.js 13中,如果设置 app 目录,该目录下的组件默认为服务端渲染组件。这意味着一切都将在服务器上运行,我们不需要特别编写 getServerSideProps 。在“app”目录下,如果你的文件名被[..id]包围,则表示它是一个动态路由。在 page.jsx 中,您可以像这样访问 id

在此处输入图像描述

 export default function ProductPage({ params }) {
  return (
    <div>
      <h1>Product ID: {params.id}</h1>
    </div>
  );
}

原文由 Yilmaz 发布,翻译遵循 CC BY-SA 4.0 许可协议

您处理页面动态路由的方式没有任何问题。问题是 API 返回的数据是一个 _数组_,但您的代码期望它是一个 _对象_。您可以从数组中检索第一项并将其传递给来自 getServerSideProps 的组件。

 export async function getServerSideProps(context) {
    const { id } = context.params; // Use `context.params` to get dynamic params
    const res = await fetch(`https://restcountries.com/v2/name/${id}`); // Using `restcountries.com` as `restcountries.eu` is no longer accessible
    const countryList = await res.json();
    const [country] = countryList; // Get first item in array returned from API

    return { props: { country } };
}

const Country = ({ country }) => {
    console.log(country);

    return (
        <>
            <h1>{country.name}</h1>
            <span>{country.capital}</span>
        </>
    );
};

export default Country;

原文由 juliomalves 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题