【问题标题】:Handle URL Parameters with Gatsby使用 Gatsby 处理 URL 参数
【发布时间】:2019-01-19 02:22:12
【问题描述】:

我正在使用 React & Gatsby 创建一个网站,并且我已经按照我想要的方式布置了所有内容,我只是在理解如何使用 URL 路由参数来更改显示的内容时遇到了一些问题。

例如,假设我有一个页面categories.js 监听http://website.com/categories,但我希望能够动态处理任何这样的 URL 参数:

http://website.com/categories/animals

当像这样使用gatsby-link 时:<Link to="/categories/animals" /> 它希望我在类别文件夹中创建一个名为animals.js 的文件。相反,我希望 categories.js 能够处理此页面的呈现,并根据 URL 参数中传递的类别选择适当的内容。

除了显示的项目外,此页面在所有类别中都完全相同,因此每个类别都有自己的静态页面没有意义。

【问题讨论】:

    标签: reactjs gatsby


    【解决方案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
        },
      })
    }
    

    我希望这是有用的。

    【讨论】:

      【解决方案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 为例,但请注意,如果页面的props 更改,您将不得不手动处理重新渲染在 React 类组件的 componentWillReceiveProps 生命周期方法中。

      但我真的不认为这是一个可靠的解决方案。

      【讨论】:

        猜你喜欢
        • 2013-10-31
        • 1970-01-01
        • 2021-02-21
        • 1970-01-01
        • 2012-02-06
        • 1970-01-01
        • 2013-08-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多