I need to run some functions (eg. Office UI Fabric React's initializeIcons()
) and AXIOS call (eg. retrieve the logged-in user with Context API) only the first time the site is hit, then store the retrieved values in the React Context and make it available to the whole application.
Gatsby is wrapping my pages' content in a Layout, like:
const IndexPage = () =>
<Layout>
Body of Index Page...
</Layout>
const AnotherPage = () =>
<Layout>
Body of Another Page...
</Layout>
with Layout being like:
const Layout = ({ children }) =>
<>
<Header />
<main>{children}</main>
<Footer />
</>
I know where I can NOT put my Context:
around the pages (or it will be executed everytime the page is hit, and also not available to the other pages):
const IndexPage = () =>
<MyContextProvider>
<Layout>
Context Available here
</Layout>
</MyContextProvider>
const AnotherPage = () =>
<Layout>
Context NOT available here
</Layout>
in the Layout (or it will be executed every time):
const Layout = ({ children }) =>
<MyContextProvider>
<Header />
<main>{children}</main>
<Footer />
</MyContextProvider>
I suppose I need a root <app>
object to surround with my Context Provider, but what's a clean way to achieve that with Gatsby?
Where should I put my Context Provider?
Context.ProviderEvery Context object comes with a Provider React component that allows consuming components to subscribe to context changes. The Provider component accepts a value prop to be passed to consuming components that are descendants of this Provider. One Provider can be connected to many consumers.
If you are using props, and you have to pass data to the last Child component amongst multiple Nested Component. The data needs to be passed through every component in the tree using props. So every component needs to know about that props data even if it's not using it. Context Solves this problem.
In order to use Redux for custom state management in a Gatsby site, you'll need to hook into two of Gatsby's extension points: Wrap the root element in your Gatsby markup once using wrapRootElement , an API supporting both Gatsby's server rendering and browser JavaScript processes.
You define a root layout. In contrast to the normal layout there are no "visible" page elements defined but hidden stuff you need on every page like ContextProviders, React Helmet, themes, etc:
RootLayout.jsx
:
export default function RootLayout({ children }) {
return (
<>
<Helmet />
<ThemeProvider theme={theme}>
<CssBaseline />
<ContextProvider>
{children}
</ContextProvider>
</ThemeProvider>
</>
);
}
Gatsby calls this root layout implicitly via gatsby-browser.js
and gatsby-ssr.js
and applies it to each of your pages. Those two identical lines of code are all you need for Gatsby to handle the rest for you.
gatsby-browser.js
:
export const wrapRootElement = ({ element }) => <RootLayout>{element}</RootLayout>;
gatsby-ssr.js
:
export const wrapRootElement = ({ element }) => <RootLayout>{element}</RootLayout>;
Summary:
References:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With