【问题标题】:Where to put Context Provider in Gatsby?在 Gatsby 中将 Context Provider 放在哪里?
【发布时间】:2020-01-23 13:53:25
【问题描述】:

我只需要在第一次访问网站时运行一些函数(例如 Office UI Fabric React 的initializeIcons())和 AXIOS 调用(例如使用 Context API 检索登录用户),然后存储检索到的值在 React Context 中并使其可用于整个应用程序。

Gatsby 将我的页面内容包装在 Layout 中,例如:

const IndexPage = () =>
<Layout>
   Body of Index Page...
</Layout>
const AnotherPage = () =>    
<Layout>
   Body of Another Page...
</Layout>

布局如下:

const Layout = ({ children }) =>
<>
    <Header /> 
    <main>{children}</main>
    <Footer />
</>

我知道我可以将我的上下文放在哪里:

  • 页面周围(或者每次点击页面都会执行,其他页面也不可用):

    const IndexPage = () =>
    <MyContextProvider>
        <Layout>
           Context Available here
        </Layout>
    </MyContextProvider>
    
    const AnotherPage = () =>    
    <Layout>
        Context NOT available here
    </Layout>
    
  • 在布局中(或者每次都会执行):

    const Layout = ({ children }) =>
    <MyContextProvider>
        <Header /> 
        <main>{children}</main>
        <Footer />
    </MyContextProvider>
    

我想我需要一个根 &lt;app&gt; 对象来围绕我的上下文提供程序,但是用 Gatsby 实现这一目标的干净方法是什么?

我应该把上下文提供者放在哪里?

【问题讨论】:

  • Here 是来自 Gatsby 官方博客的一篇很棒的博文,可能有助于解决您的需求。
  • 谢谢@LionelT。这基本上是我尝试过的,排除了 localStorage (这对于保存主题很好,但对于登录用户 AFAIK 则不行)。我可以使用 sessionStorage (但随后我需要处理从同一台电脑登录的两个不同用户,并且不关闭浏览器......),我只是希望有一种方法可以“存储" Axios 调用的结果并避免再次执行它 - 无需使用一些 HTML5 存储......无论如何,我会尽快探索它

标签: javascript reactjs axios gatsby react-context


【解决方案1】:

您定义一个根布局。与正常布局相比,没有定义“可见”页面元素,但每个页面上都隐藏了您需要的东西,例如 ContextProviders、React Helmet、主题等:

RootLayout.jsx:

export default function RootLayout({ children }) {
  return (
    <>
      <Helmet />
        <ThemeProvider theme={theme}>
          <CssBaseline />
          <ContextProvider>
            {children}
          </ContextProvider>
        </ThemeProvider>
    </>
  );
}

Gatsby 通过gatsby-browser.jsgatsby-ssr.js 隐式调用此根布局并将其应用于您的每个页面。这两行相同的代码就是 Gatsby 为您处理其余部分所需要的全部内容。

gatsby-browser.js:

export const wrapRootElement = ({ element }) => <RootLayout>{element}</RootLayout>;

gatsby-ssr.js:

export const wrapRootElement = ({ element }) => <RootLayout>{element}</RootLayout>;

总结:

  • 您将上下文提供程序放在根布局中。

参考资料:

  • 我问过相关问题herehere。我在此答案中提供的代码是您和我的问题的解决方案。如果您的整个应用需要这些信息,那么从 React Redux 等框架改编而来的良好编码实践是使用 Context Provider 包装您的整个应用。
  • 提到了blog post@Lionel T。

【讨论】:

  • 好的,您的其他问题 (There's no built-in mechanism for persisting state between page loads, so you'll need to reach for another tool for that) 的答案中的句子表明我需要“手动”为 Auth 部分实施一些 cookie 或 sessionStorage 解决方案。至少现在我确信在 Gatsby 中没有什么开箱即用的东西,谢谢
  • @AndreaLigios 是的,正确的。我的解决方案是实现 json web 令牌,以便将重复用户识别为您提到的建议的答案。
【解决方案2】:

为了完整起见,Gatsby 提供的 API(通过 gatsby-browser.js只运行一次函数是:

onClientEntry

export const onClientEntry = () => {
    console.log("Browser started!")
    // Put here run-only-once functions 
}

onInitialClientRender

export const onInitialClientRender = () => {
    console.log("First rendering completed!")
    // Put here run-only-once functions which need rendered output
}

【讨论】:

    猜你喜欢
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多