我正在使用React&Gatsby创建一个网站,并且已经按照我想要的方式进行了布局,我在理解如何使用URL Route参数来更改显示的内容时遇到了一些问题。
例如,假设我有一个页面categories.js
可以监听http://website.com/categories
,但是我希望能够动态处理任何URL参数,例如:
http://website.com/categories/animals
当像这样使用gatsby-link
时:<Link to="/categories/animals" />
它要我在Categories文件夹中创建一个名为animals.js
的文件。相反,我希望category.js能够处理此页面的呈现,并根据URL参数中传递的类别选择适当的内容。
除了显示的项目外,该页面在所有类别中都是完全相同的,因此对于每个类别都拥有自己的静态页面并不有意义。
答案 0 :(得分:2)
我认为您说错了
除了显示的项目外,该页面在所有类别中都是完全相同的,
因此,每个类别都没有自己的静态页面是没有意义的。
实际上,这正是我发现 GatsbyJS 如此有用的地方,因为这是一个静态网站生成器。
这意味着您可以为Gatsby提供一个template
组件,该组件将为所有类别提供相同的布局,然后Gatsby将在构建时为您获取数据并创建静态页面 >。
Gatsby不仅限于使用像许多静态站点生成器这样的文件制作页面。通过Gatsby,您可以在构建时使用GraphQL查询数据并将数据映射到页面。 (from Gatsby official tutorial)
这个主意是这样的:
/gatsby-node.js中的
const path = require(`path`); // you will need it later to point at your template component
exports.createPages = ({ graphql, boundActionCreators }) => {
const { createPage } = boundActionCreators;
// we use a Promise to make sure the data are loaded
// before attempting to create the pages with them
return new Promise((resolve, reject) => {
// fetch your data here, generally with graphQL.
// for example, let say you use your data from Contentful using its associated source plugin
graphql(`
{
allContentfulCategories {
edges {
node {
id
name
description
# etc...
}
}
}
}
`).then(result => {
// first check if there is no errors
if (result.errors) {
// reject Promise if error
reject(result.errors);
}
// if no errors, you can map into the data and create your static pages
result.data.allContentfulCategories.edges.forEach(({ node }) => {
// create page according to the fetched data
createPage({
path: `/categories/${node.name}`, // your url -> /categories/animals
component: path.resolve('./src/templates/categories.js'), // your template component
context: {
// optional,
// data here will be passed as props to the component `this.props.pathContext`,
// as well as to the graphql query as graphql arguments.
id: node.id,
},
});
});
resolve();
});
});
};
然后您只需在模板组件上获取数据
在/src/templates/categories.js中的
import React from "react";
export default ({ data: { contentfulCategories: category } }) => {
return (
<div>
<h1>{category.name}</h1>
<div>{category.description}</div>
</div>
);
};
// we can query the needed category according to the id passed in the
// context property of createPage() in gatsby-node.js
export const query = graphql`
query CategoryQuery($id: String!) {
contentfulCategories(id: { eq: $id }) {
name
description
}
}
`;
如果您坚持动态呈现categories
页,可以举this question的示例,该示例与您的示例相似,但是请注意,如果页面的在{strong> React 类组件的props
生命周期方法中进行了componentWillReceiveProps
的更改。
但是我真的不认为这是一个可靠的解决方案。
答案 1 :(得分:1)
编辑:
经过永久搜索,我找到了更好的答案! -
https://github.com/gatsbyjs/gatsby/issues/13965#issuecomment-617364363
您认为您的案例示例如下:
gatsby-node.js
:
createPage({
path: `/categories/:id`,
matchPath: `/categories/:id`,
component: path.resolve(`./src/pages/categories.js`),
})
categories.js
:
import React from "react"
export default function Booking({ id }) {
return <div>categories #{id}</div>
}
旧答案:
我似乎也遇到了完全相同的问题,也找不到任何答案。我的想法是也使用gatsby-node.js
文件,但我不使用graphQL查询任何内容。
我的 /src/templates/categories.js 版本:
const path = require(`path`)
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
createPage({
path: `/categories/animals`,
component: path.resolve(`./src/pages/categories.js`),
// The context is passed as props to the component as well
// as into the component's GraphQL query.
context: {
id: `animals`, //use this context parameter to do the dynamic stuff in your page
},
})
}
我希望这是有用的。