【问题标题】:Pass custom prop or data to Next JS Link component将自定义 prop 或数据传递给 Next JS Link 组件
【发布时间】:2020-09-07 16:13:08
【问题描述】:

我已经开始使用 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;

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

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

【问题讨论】:

    标签: javascript reactjs next.js


    【解决方案1】:

    您不能将数据传递给next/link 组件。

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

    【讨论】:

    • 是的,你是对的。我是 SSR 的新手,现在我想多了,你说的很有意义。
    【解决方案2】:

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

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

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

    const RoutedComponent = () => {
      useEffect(() => {
        const { data } = getQueryParams(window.location.search);
      }, []);
    };
    

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

    【讨论】:

    • 感谢您的回复。我明白你在说什么,但这会导致一个非常混乱的 URL :-) 我是 SSR 的新手,现在我想得更多,状态不能像客户端一样从一个视图传递到另一个视图是有道理的渲染。
    • 亲爱的@oldo.nicho,还有另一种方法,请参阅After.js。这是一个很棒的库,在next.js 中使用了react-router。所以有了这个,你可以解决你的问题。如果您对此感到满意,请告诉我更新我的答案。
    • 感谢@AmerllicA 的建议。我看了一下 After.js,确实它看起来可能是一个不错的解决方案,但是我目前正将精力集中在学习 Next.js 上,我更愿意学习如何在此限制内操作图书馆,然后再扩展到另一个图书馆。不错的建议,希望其他人会觉得它有用。
    • 可能有更好的方法来使用next/router做同样的事情,如this答案所示
    • 这是工作,我用这个方法。非常感谢
    【解决方案3】:

    添加到@AmerllicA 的答案,

    我找到了一种在使用getServerSideProps 点击&lt;Link&gt; 组件时将道具传递到目标页面的方法

    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>
    

    在pages/episodes/[id].js

    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
            }
        }
    }
    

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

    终于可以在剧集画面中使用传递的道具了

    const Episode = (props) => {
        return (
            <div>{props.title}</div>
        )
    }
    

    我认为这也适用于 getStaticProps。

    感谢您的提问。

    【讨论】:

    • 谢谢你这对我来说很完美,而且很容易理解
    猜你喜欢
    • 2018-09-21
    • 2018-11-16
    • 2020-06-12
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 2022-07-12
    相关资源
    最近更新 更多