将自定义 prop 或数据传递给 Next JS Link 组件

old*_*cho 24 javascript reactjs next.js

我开始摆弄 Next JS,并且遇到了第一个障碍。我正在创建一个显示一堆播客剧集的页面,并在主页上为每个播客显示一个小预览卡。卡组件看起来像这样:

import React from 'react';
import Link from 'next/link';
import { kebabCase } from 'lodash';
import { format } from 'date-fns';
import TextTruncate from 'react-text-truncate';

import { Episode as EpisodeInterface } from '../../interfaces';

type Props = {
  episode: EpisodeInterface;
};

const Episode: React.FunctionComponent<Props> = ({ episode }) => {
  return (
    <Link
      href="episodes/[id]"
      as={`episodes/${episode.itunes.episode}-${kebabCase(episode.title)}`}
    >
      <div className="group transition duration-500 cursor-pointer rounded-lg overflow-hidden shadow-lg border border-cream-darker bg-surface hover:bg-surface-hover hover:border-surface-hover hover:text-text-hover">
        <div className="px-6 py-6">
          <div className="font-bold font-serif text-3xl mb-2">
            {episode.title}
          </div>

          <div className="transition duration-500 flex justify-between mb-2 text-gray-700 group-hover:text-text-hover">
            <span>Episode {episode.itunes.episode}</span>
            <span>{format(new Date(episode.isoDate), 'd MMMM yyyy')}</span>
          </div>

          <div className="mb-2">
            <TextTruncate line={3} text={episode.contentSnippet} />
          </div>
        </div>
      </div>
    </Link>
  );
};

export default Episode;
Run Code Online (Sandbox Code Playgroud)

现在,我希望能够将对象传递到位于通过上面的元素链接到的episode完整剧集页面,而不必根据我选择的路线名称重新获取和过滤所有剧集。/pages/episodes/[id].tsxLinkepisodes/${episode.itunes.episode}-${kebabCase(episode.title)}

  • 是否可以将整个episode对象传递给新视图?
  • 如果没有,是否可以将一些更具体的数据(例如唯一的 ID)传递到视图,这将使我能够更好地识别情节,而不用查询参数扰乱路线?

Zak*_*sri 18

添加到@AmerllicA的答案,

<Link>我找到了一种在单击组件时将道具传递到目标页面的方法getServerSideProps

Nextjs 链接组件文档 https://nextjs.org/docs/api-reference/next/link

Nextjs getServerSideProps 文档 https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering

href您可以将自定义对象传递给prop的查询选项

<Link
    href={{
        pathname: "episodes/[id]",
        query: {
            id: episode.itunes.episode,
            title: episode.title
        }
    }}
    as={`episodes/${episode.itunes.episode}-${kebabCase(episode.title)}`}
 >
... button stuff
</Link>
Run Code Online (Sandbox Code Playgroud)

pages/episodes/[id].js



export  const getServerSideProps= (context)=> {
  console.log(context.query) 
  return {
      props: { 
         title: context.query.title //pass it to the page props
      }
  }
}
export async function getServerSideProps  (context) {
    console.log(context.query) 
    // returns { id: episode.itunes.episode, title: episode.title}
    

    //you can make DB queries using the data in context.query
    return {
        props: { 
           title: context.query.title //pass it to the page props
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并且可以console.log在终端看到数据来确认数据通过

最后,您可以在剧集屏幕中使用传递的道具

const Episode = (props) => {
    return (
        <div>{props.title}</div>
    )
}
Run Code Online (Sandbox Code Playgroud)

getStaticProps我认为这也适用。

感谢你的提问。

  • 谢谢,这对我来说很完美并且很容易理解 (4认同)

Ame*_*icA 9

实际上,由于这个链接,这是一个悬而未决的问题,NextJS 没有适当的解决方案。根据NexJS 文档,您只需将query参数传递给路由组件即可。所以我知道这不是一个解决方案,但现在它可以解决您的问题:

<Link href={{ pathname: '/about', query: { data: JSON.stringify(episode) } }}>
  <a>About us</a>
</Link>
Run Code Online (Sandbox Code Playgroud)

然后在路由组件中从 URL 获取查询parse

const RoutedComponent = () => {
  useEffect(() => {
    const { data } = getQueryParams(window.location.search);
  }, []);
};
Run Code Online (Sandbox Code Playgroud)

注意:这getQueryParams是一个简单的函数,它返回?URL 中 后面的所有参数数据。

  • 亲爱的@oldo.nicho,还有另一种方法,请参阅[After.js](https://github.com/jaredpalmer/after.js)。这是一个很棒的库,在“next.js”中使用了“react-router”。所以有了这个,你就可以解决你的问题。如果您对此同意,请告诉我更新我的答案。 (2认同)
  • 感谢@AmerllicA 的建议。我看了一下 After.js,确实它看起来可能是一个不错的解决方案,但是我目前正在集中精力学习 Next.js,我更愿意学习如何在这个限制下进行操作图书馆,然后再扩展到另一个图书馆。不过,很好的建议,希望其他人会发现它有用。 (2认同)

Nik*_*lev 7

您无法将数据传递给next/link组件。

即使您通过了它,当用户直接访问页面或刷新页面时,您也将无法在服务器端访问它。

  • 你是对的。我是 SSR 新手,现在我想得更多了,你说的很有意义。 (3认同)