【问题标题】:Gatsby dynamic routes: 404 instead of component, can't configureGatsby 动态路由:404 而不是组件,无法配置
【发布时间】:2023-01-31 17:48:47
【问题描述】:

我用 Gatsby.js 做了一个简单的站点,无法配置动态路由。

我有 index.js 页面(由 React 自动创建),看起来像:

import * as React from 'react'
const IndexPage = () => {

  return (
      <Layout
        pageTitle="Home Page"
      >
       Some text for my main page
      </Layout>
  )
}

export const Head = () => <title>Home Page</title>

export default IndexPage

布局组件包括如下所示的页眉:

import React, { useState, useEffect } from 'react';
import { Link } from 'gatsby';

const Header = () => { 

  return (
    <Wrapper style={{ *some styles* }}>
     <Link to="/">Index</Link>
     <Link to="/projects">Projects</Link >
   </Wrapper>
)
};

export default Header;

我的项目页面如下所示:

import * as React from 'react'
import { BrowserRouter, Route, Routes } from 'react-router-dom'

import Layout from '../layout'

const Projects = () => {

return (

<BrowserRouter>
      <Layout>
           <Wrapper>
               <Routes>
                    <Route path="projects/:projectID/" component={ProjectDetails} />
                </Routes>
                 <MyProjectLink to="/projects/1"> 
                     Project 1
                 </MyProjectLink>
                    <MyProjectLink to="/projects/2">
                     Project 2
                   </MyProjectLink>
             </Wrapper>
        </Layout>
</BrowserRouter>
)

}

export const Head = () => <title>Our Projects</title>

export default Projects

我有我的 ProjectDetails 组件:

import React from 'react';
import { useParams } from 'react-router';

import Layout from '../../pages/layout';

const ProjectDetails = () => {

    const { projectID } = useParams();

    return (
        <Layout>
            <Wrapper>
                <h2>Project {projectID}</h2>
            </Wrapper>
        </Layout>
    );
}

export default ProjectDetails;

问题是,当我导航到 localhost:8000/projects/1(或“2”、“3”或“100500”)时,我看到一个 404 页面而不是我的项目详细信息组件。

我已经尝试将索引页面包装到 BrowserRouter 并将路由与我的路由一起移动到那里,但在我看来这是一个愚蠢的想法(而且它不起作用)。

我错过了什么?我不知道的 Gatsby (v5) 的一些特性?我是 Getsby 的新手,老实说,我认为这里的动态路由与 React Router 中的工作方式相同。

【问题讨论】:

  • 您如何创建页面(项目)?您是要创建仅供客户使用的路线还是只是项目的模板?
  • 这就是我现在所做的一切:创建模板组件。在我看来,我必须为这些页面创建降价,然后在 gatsby-node 中使用 createPage 进行一些配置,对吗?

标签: reactjs routes gatsby


【解决方案1】:

Gatsby 从 React 扩展其路由,但是,创建仅客户端路由的方式略有不同。

据我了解您的代码,您正在尝试为项目创建一个模板页面:这可以通过在 /templates 文件夹中创建一个文件来简单地完成。像这样的简单组件应该可以工作:

const Projects = ({ data }) => {
  return (
    <Layout>
      <Wrapper></Wrapper>
    </Layout>
  );
};


export const Head = () => <title>Our Projects</title>

export default Projects

这个模板,只要你在创建页面时使用它(使用gatsby-node.jsFile System Route API)将被用来保存每个特定的项目数据。

每个项目数据都将使用 GraphQL 进行查询,并保存在props.data 中,但在不知道您的来源(可以是 markdown、JSON、CMS 等)的情况下,我无法提供示例查询。

一旦 Gatsby 从您的数据源推断出其 GraphQL 节点,您就可以使用它来获取所有项目、特定项目或任何页面/模板 (page query) 或什至使用 static queries 所需的任何其他 GraphQL 数据。

这个想法应该类似于:

// gatsby-node.js
projects.forEach(({ node }, index) => {
  createPage({
    path: node.fields.slug,
    component: path.resolve(`./src/templates/project.js`),
    context: {
      title: node.title, 
    },
  })
})

在您的gatsby-node.js(或文件系统路由 API)中,您可以获得所有项目,循环遍历它们,并为每个项目提供 createPage。每个项目的路径 (URL) 将是 slug 字段 (node.fields.slug),但您可以使用任何您想要的。 Gatsby 会根据这个字段创建动态页面。

然后您决定将哪个组件用作模板:path.resolve(./src/templates/project.js) 在这种情况下,最后,您填充上下文以添加唯一值(title 在这种情况下:同样,这可以是 idslug 等)。该值将用于过滤模板中的节点。

在你的Project模板中:

export const query = graphql`
  query ($title: String) {
    mdx(title: {eq: $title}) {
      id
      title
    }
  }
`

在这种情况下,我使用基于 markdown 的来源(这就是 mdx 节点的原因)并且该节点使用上下文值按标题 ($title) 进行过滤。数据将在模板的props.data 内。同样,如果您想获取所有项目,您将有可用的 allMarkdownallMdx(或 allJSON...),具体取决于源节点)

【讨论】:

    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 2020-02-29
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多