0

我正在开发一个 Gatsby 项目(一个语言学习博客),并且遇到了一个问题,该问题仅在生产版本中发生,因为服务器端渲染。

我使用以下方案以编程方式为每篇博客文章生成一个页面: /posts/{post-name}. 每个帖子还可以有许多子路径映射到 UI 中的打开选项卡。例如,/posts/important-spanish-verbs/lesson将打开课程选项卡。每个页面都有一个 的matchPath属性/posts/{post-name}/*,这些被处理为仅限客户端的路由,使用reach-router.

使用gatsby develop,应用程序完全按照预期工作。当我访问时/posts/some-post/podcast,它成功打开到播客选项卡,我可以看到活动选项卡设置正确。

问题在于gatsby build && gatsby serve,当我重新加载直接导航到帖子内特定选项卡的 URL 时(手动访问整个 URL 或刷新),UI 中的活动选项卡设置正确。

以下片段(高度简化和浓缩以演示问题)大致概述了问题:

function TabbedLayout({ children, basePath }) {
  return (
    <LocationProvider>
      {({ location }) => {
        return (
          <Fragment>
            <ul>
              React.Children.map(children, (child, index) => {
                const isActive = child.props.path === location.pathname
                console.log(`tab ${child.props.path} active? ${isActive}`)
                return <li className={isActive ? 'active' : 'inactive'}>{/* construct a link based on child props */}</li>
              })
            </ul>
            <Router basepath={basePath}>
              {children}
            </Router>
          </Fragment>
        )
      }}
    </LocationProvider>
}

当我运行使用上面在生产构建(使用 SSR)中演示的方法的代码时会发生什么,例如,当我访问时posts/example-post/lesson

  • 内容通过 Reach 路由器正确呈现(即课程选项卡的内容打开)
  • 课程标签有课程inactive(错误)
  • 在控制台中,我看到tab /posts/example-post/lesson active? true打印出来了,即使 CSS 类没有更新!

我已经尝试了所有我能想到的尝试更新 UI。一旦我单击不同的选项卡并且窗口位置更改而没有刷新,一切都会更新正常并且活动选项卡 UI 按预期工作,但我似乎无法让它根据isActive变量重新呈现。

有谁知道解决或解决此问题的方法?

谢谢!

4

1 回答 1

3

我设法找到了解决该问题的方法,尽管无法详细了解问题实际发生的原因有点令人沮丧。

如果我将 tab <li>(在第一次使用 SSR 加载时未正确显示为活动/非活动)以检查我们是否在浏览器中,它可以工作:

return typeof window !== 'undefined' && (
  <li className={isActive ? 'active' : 'inactive'}>
    {/* construct a link based on child props */}
  </li>
)
于 2020-01-20T19:25:34.747 回答