【问题标题】:Dynamic routing with getServerSideProps in NextjsNextjs 中使用 getServerSideProps 进行动态路由
【发布时间】:2020-07-28 01:38:30
【问题描述】:

我正在努力学习 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 动态路由正常。例如,当您单击阿富汗时,URL 会显示http://localhost:3000/p/Afghanistan

我的国家组件没有显示任何内容,undefined 被打印到终端。

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

{
name: "Afghanistan"
}

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

【问题讨论】:

    标签: javascript reactjs next.js server-side-rendering


    【解决方案1】:
    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,
        },
      };
    

    【讨论】:

    • 如果它对任何人有帮助,这个回复是完全不正确的——尽管它可能已经过时了。在 2020 年 next 的 getServerSideProps 要求您返回一个包含关键字 props 的对象,以便您的 props 进入与它一起导出的组件中。
    • 好吧,我不完全确定你说的是真的,我的陈述基于(a)下一个 js 文档中明确说明的内容,以及(b)我的工作自己的代码....
    • 标题指的是 getServerSideProps ...... OP 是 getServerSideProps ......你自己的答案是 getServerSideProps ......我的评论是关于 getServerSideProps ......那你为什么现在谈论 getInitialProps ? ?!!
    • (虽然我也想说它们不一致,因为它们都在同一框架内提供非常相似的功能,但这可能与向后兼容性有关)
    【解决方案2】:

    只是为了添加到接受的答案,您还可以解构以使其(恕我直言)更具可读性。这完全是可选的

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

    【讨论】:

      【解决方案3】:

      您处理页面动态路由的方式没有任何问题。问题是 API 返回的数据是一个 array,但您的代码期望它是一个 object。您可以从数组中检索第一项并将其从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;
      

      【讨论】:

        猜你喜欢
        • 2023-02-11
        • 2022-11-25
        • 2022-08-24
        • 1970-01-01
        • 1970-01-01
        • 2022-06-16
        • 2020-09-08
        • 2021-08-12
        • 2020-08-25
        相关资源
        最近更新 更多