【问题标题】:Gatsby hybrid app - Issues with sub routing on a page which is built using a template in `createPage`Gatsby 混合应用程序 - 使用“createPage”中的模板构建的页面上的子路由问题
【发布时间】:2019-08-09 08:18:32
【问题描述】:

编辑: 我忘了提到我的网站包含从这个模板构建的大约 25k 页面。 Derek Nguyen 的答案适用于页面数量较少的小型网站,但当扩大规模时,matchPath 数据存储在 JS 中,导致捆绑包大小很大。 (对我来说大约 3.1mb!)

挑战

我需要使用 createPage 创建一个页面,其中包含一个子路由系统,其中默认路由构建为静态 HTML,但任何其他路由都是客户端专用的。

问题

我有一个模板组件,用于在 createPage 方法中生成静态 HTML,还有一个位于 pages/ 目录中的组件,用于为仅限客户端的路由分配一个 matchPath

在最新版本的 Gatsby 上,模板组件呈现为默认路由,但随后“页面”组件呈现为仅限客户端的组件,当我只希望子路由到时,导致整页重新呈现渲染,因为父路由中有数据需要持久化。

在我的脑海中,有两个组件和两个路由器似乎是错误的,但我想不出任何其他方法来实现我想要实现的目标。

这是我的路由设置示例:

createPage使用的模板

<Router>
  <ContainerComponent
     path={urlFromGraphQL}
  >
    <DefaultRoute
      default
    />
  </ContainerComponent>
</Router>

/pages 中的仅客户端组件

<Router>
  <ContainerComponent
     path="/some-route/:slug/:id"
  >
    <DefaultRoute
      default
    />
    <SecondTabRoute
      path="second-tab-route"
    />
    <ThirdTabRoute
      path="third-tab-route"
    />
  </ContainerComponent>
</Router>

我也复制了codesandbox 中的行为。确保转到https://hkhbb.sse.codesandbox.io/test/foo/bar 以查看正确的输出。

我已经在 github 上创建了一个 issue 关于这个但还没有回复。

【问题讨论】:

    标签: javascript reactjs routing gatsby reach-router


    【解决方案1】:

    问题

    看起来您正在混合静态生成的页面和动态页面,即您都在/test/foo/bar 生成一个页面,同时在test.js 中匹配test/:param1/:param2

    静态生成的页面将比动态页面具有更高的特异性,因此 Gatsby 认为 test/foo/bartest/foo/bar/second-route 是 2 个不同的页面,而不是来自同一个静态页面的 2 个动态路由。

    可能的解决方案

    在这种情况下,您需要做的是 both /test/test/foo/bar 动态路由的根页面。这样,/test/one/two 这样的随机匹配将是/test 的动态路由;而/test/foo/bar/second-route 将是/test/foo/bar 的动态路由。

    由于您已经以编程方式创建了/test/foo/bar,因此将其作为动态页面的根很简单:

      // gatsby-node.js
      exports.createPages = async ({ actions }) => {
        const { createPage } = actions
        const pathFromGraphQL = "/test/foo/bar"
    
        createPage({
          component: path.resolve(`./src/templates/template.js`),
          context: {
            url: pathFromGraphQL,
          },
          path: pathFromGraphQL,
    +     matchPath: `${pathFromGraphQL}/*`,
        })
      }
    
    

    现在的问题是“template.js”不再完全是一个模板,它必须包含特定于test/foo/bar 的组件和路由。根据您的要求,这可能是一个阻碍,也可能以某种方式被规避。

    我稍微编辑了你的 fork 来证明这一点;除了上面的代码更改之外,pages/test.js 的代码被移动到templates/template.js 并且我为pages/test.js 添加了一个虚拟组件,以表明它仍然可以处理其他动态路由:

    此外,如果您决定这样做,请注意此'wont-fix' bug

    【讨论】:

    • 谢谢!我忘了提到,在我的例子中,我们根据这些模板生成了 25k 页面。我沿着matchPath 直接在createPage 选项中提供createPage 的路线走下去,你是对的,它工作正常。唯一的问题是,从 Gatsby v2.9.0 开始,包含matchPath 数据的数组被捆绑到 JS 中。这会为具有大量页面的站点生成一个庞大的 JS 包。我最初为此创建了一个issue,这导致了我目前打开的那个!
    • 哇,是的,这对你没有帮助:/我会关注这个问题并看看是否有其他解决方案出现
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多