Node.js 如何根据单击的项目id创建显示页面
我正在创建通过.map函数循环的项目列表。我希望这些项目中的每一个都在一个单独的页面上呈现一些其他细节Node.js 如何根据单击的项目id创建显示页面,node.js,json,reactjs,graphql,gatsby,Node.js,Json,Reactjs,Graphql,Gatsby,我正在创建通过.map函数循环的项目列表。我希望这些项目中的每一个都在一个单独的页面上呈现一些其他细节 import React from 'react' import {faArrowRight, faMusic, faPlay, faPlayCircle, faTachometerAlt} from "@fortawesome/free-solid-svg-icons"; import {FontAwesomeIcon} from "@fortawesome/r
import React from 'react'
import {faArrowRight, faMusic, faPlay, faPlayCircle, faTachometerAlt} from "@fortawesome/free-solid-svg-icons";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import music from '../mocks/music.json'
import { Link } from 'gatsby'
import Music from '../pages/music'
const newData = music.map( (data) => {
return (
<div className="row no-gutters justify-content-between align-items-center">
<div className="col-auto">
<button className="btn-gradient btn-circle">
<FontAwesomeIcon icon={faPlayCircle} />
</button>
</div>
<div className="col">
<div className="music-list-content">
<span className="artist">{data.author}</span>
<Link to={`/music/${data.id}`}>{data.title}</Link>
<span className="play">
<FontAwesomeIcon icon={faPlay} /> {data.duration}
</span>
</div>
</div>
<div className="col-auto">
<span className="badge-dark badge">{data.genre}</span>
</div>
</div>
)
})
const membersToRender = music.filter(member => member.id)
const numRows = membersToRender.length
const Musics = () => {
return (
<div>
<div className="title">
<h5>New Music</h5>
<span>{numRows} new songs</span>
</div>
<div>
<div className="music-list card-wrapper">
{newData}
</div>
</div>
<div className="footer-wrapper">
<div>
<FontAwesomeIcon icon={faMusic} />
<span>Song Library</span>
</div>
<FontAwesomeIcon icon={faArrowRight} />
</div>
</div>
)
}
export default Musics
从“React”导入React
从“@fortawesome/free solid svg icons”导入{faArrowRight、faMusic、faPlay、faPlay circle、fatachmeteral}”;
从“@fortawesome/react fontawesome”导入{FontAwesomeIcon}”;
从“../mocks/music.json”导入音乐
从“盖茨比”导入{Link}
从“../pages/Music”导入音乐
const newData=music.map((数据)=>{
返回(
{data.author}
{data.title}
{data.duration}
{data.genre}
)
})
const membersToRender=music.filter(member=>member.id)
const numRows=membersToRender.length
常数音乐=()=>{
返回(
新音乐
{numRows}新歌
{newData}
歌曲库
)
}
导出默认音乐
我创建了一个链接,每当我点击它时,它就会将我带到另一个附加了id和.js扩展名的页面(找不到页面)
拜托,你怎么办?我想点击标题并将其显示在整个页面上。您应该使用React Router()进行一些路由
因此,链接必须指向交换机中的路由,如链接示例中所示。您的逻辑似乎很好,但是,您缺少了最重要的部分,即页面创建,因为您没有创建页面,所以所有链接都会断开 在《盖茨比》中,有两种不同的页面创建方式:
- 使用
动态创建页面:当处理大量数据(如JSON)时,让gatsby处理为gatsby创建页面的责任会更容易。由于您是从一个JSON中获取资源,所以需要将所有内容都设置为 注意:我假设您的JSON是正确定义和格式化的,包含我查询的所有字段 您的gatsby node.js
必须是一个模板(位于musicTemplate
文件夹内) 请注意,您正在通过盖茨比的上下文传递一些字段,这意味着这些字段将通过模板中的/templates
可用。因此,创建一个模板,如:props.pageContext
import React from "react" import Layout from "../components/layout" export default function MusicTemplate({pageContext}) { return ( <Layout> <div>Hello musician {pageContext.title}</div> </Layout> ) }
因此,正如我所说的,通过这种方法,您可以基于JSON文件创建动态页面,它们将在从“React”导入React 从“./组件/布局”导入布局 导出默认函数MusicTemplate({pageContext}){ 返回( 你好,音乐家{pageContext.title} ) }
中可用,并且指向那里的所有引用和链接都是有效的 我还建议使用/从该循环中的JSON检索数据。如果从该数据(在一个单独的组件中)创建一个静态查询,您将能够在整个项目中按需获取它,因此您将重用一个有趣的逻辑部分。最好使用它,而不是直接请求JSON 你可以按照你需要的去做localhost:8000/music/{music.slug}
- 在
文件夹中添加/pages
文件:盖茨比推断/pages文件夹的内部结构,并根据该结构创建相应的页面。例如,如果您的结构类似于:.js
Gatsby将创建一个类似于/pages/mummers/name1.js
的页面localhost:8000/mummers/name1
如前所述,第一种方法适合您的需求,并且对于此用例更为可取,因为第二种方法的可扩展性和可维护性较差。如果您在此基础上进行扩展,并提供一个示例,以便您的问题不依赖于链接,那么这将是一个更好的答案。问题还提到了gstsby,所以我认为最好使用LinkHi,谢谢。。。请,我想知道我是否需要删除.map函数并替换为上面的代码,或者我只需要创建Gatsby-node.js并添加代码,还需要为另一个创建模板文件。同时,我想实现的是点击上面代码中显示的标题,然后打开一个单独的页面,其中包含针对特定项目完整编写的所有详细信息以及相应的代码。您需要删除您的代码,并用我提供的代码替换它。通过这种方法,您可以在
gatsby node.js
中创建页面,并且在项目的任何页面中,您都可以链接到所创建的页面(/music/payne
)。在这里,您将列出该音乐家的所有信息,因为它是在模板组件中编码的。我在代码中使用了第二种方法,一切都很完美。此外,使用第二种方法,我计划将其显示在当前页面上(列表上方),它将显示未定义的pageContext.title。当然,页面在提供上下文之前没有上下文,只有在gatsby node.js
中提供上下文时,上下文才起作用(第一种方法)
import React from "react"
import Layout from "../components/layout"
export default function MusicTemplate({pageContext}) {
return (
<Layout>
<div>Hello musician {pageContext.title}</div>
</Layout>
)
}