如何在使用 root-wrapper 为 Gatsby 提供主题时使用页面查询

Posted

技术标签:

【中文标题】如何在使用 root-wrapper 为 Gatsby 提供主题时使用页面查询【英文标题】:How to use page query while using root-wrapper for providing Theme with Gatsby 【发布时间】:2020-11-16 11:31:51 【问题描述】:

我在 gatsby 中使用 wrapRootElement 函数在根元素上提供 ThemeProviderstyled-component。这是代码:

export const wrapRootElement = () => 
  if (typeof window === 'undefined') return <span>Something went wrong!</span>
  return(
      <ThemeProvider theme=theme>
         <FadeTransitionRouter>
            <Page path="/" page=<IndexPage /> />
            <Page path="/plan" page=<PlanPage /> />
            <Page path="/promos/:slug" page=<Template /> />
        </FadeTransitionRouter>
      </ThemeProvider>
);

因此,我不得不在页面中使用 staticQuery,因为页面查询在那里不起作用。但我需要使用页面查询在graphql 查询中引入变量。我怎样才能做到这一点?如果我不使用wrapRootElement,我的页面查询工作正常。但对我来说使用它很重要,因为我需要为所有页面提供我的外部主题。

提前致谢。

【问题讨论】:

【参考方案1】:

您没有在此处包装根元素,而是替换了整个 Gatsby 应用程序树。您可能会看到有关页面查询被忽略的警告,因为它们位于未像页面一样处理的文件中,这很可能是造成混乱的原因。

这是 Gatsby 文档提供的示例:

exports.wrapRootElement = ( element ) => 
  return (
    <Provider store=store>
      element
    </Provider>
  )

注意这个例子如何接受一个element 属性,它作为子级传递给Provider 组件?这就是你所缺少的。你可能想要这样的东西:

export const wrapRootElement = ( element ) =>
  <ThemeProvider theme=theme>
    element
  </ThemeProvider>

您无需在此处检查window 的存在。如果你在gatsby-browser.js,它只会在浏览器的上下文中执行。如果你在gatsby-s-s-r.js 中,它只会在 node 的上下文中执行。无论哪种方式,它们都需要产生相同的 DOM 输出才能干净地使用 React 水合物。以您展示的方式进行操作会导致在 React 水合物时替换整个 DOM,这比客户端渲染的应用程序效率低。

最后,我删除了FadeTransitionRouter 位,因为您还没有分享它是什么,而且它不太可能与 Gatsby 路由兼容。如果你想要页面转换,this page in the documentation has details on how to set this up。

【讨论】:

感谢您的回答。如果我按照您所说的方式进行操作,我将如何进行路由?假设我在 pages/ 文件夹中有 3 页。我应该在 element 地方写什么?抱歉,我是新手,所以在这里需要帮助。 Gatsby 为您处理路由。查看我分享的文档链接,了解如何在 Gatsby 的上下文中处理页面转换。 @PraveshChoudhary 这回答了您的问题还是您仍然需要帮助?

以上是关于如何在使用 root-wrapper 为 Gatsby 提供主题时使用页面查询的主要内容,如果未能解决你的问题,请参考以下文章

在Gatsby中设置环境变量

Gatsby / Webpack Polyfill 问题

在盖茨比中,扩展组件与箭头功能有啥区别[重复]

ACF 自定义字段 WP GraphQL 突然开始在 Gatsby 中返回 null,即使它曾经可以工作

从 Gatsby JS 制作 Axios post Req

BLE开发之GATT