Access React context outside of component
Asked Answered
G

1

11

I'm using React context to store the locale for a NextJS website (e.g. example.com/en/). The setup looks like this:

components/Locale/index.jsx

import React from 'react';

const Context = React.createContext();
const { Consumer } = Context;

const Provider = ({ children, locale }) => (
  <Context.Provider value={{ locale }}>
    {children}
  </Context.Provider>
);

export default { Consumer, Provider };

pages/_app.jsx

import App, { Container } from 'next/app';
import React from 'react';

import Locale from '../components/Locale';


class MyApp extends App {
  static async getInitialProps({ Component, ctx }) {
    const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
    const locale = ctx.asPath.split('/')[1];
    return { pageProps, locale };
  }

  render() {
    const {
      Component,
      locale,
      pageProps,
    } = this.props;

    return {
      <Container>
        <Locale.Provider locale={locale}>
          <Component {...pageProps} />
        </Locale.Provider>
      </Container>
    };
  }
}

So far so good. Now within one of my pages, I get data from Contentful CMS API in the getInitialProps lifecycle method. That looks a bit like this:

pages/index.jsx

import { getEntries } from '../lib/data/contentful';

const getInitialProps = async () => {
  const { items } = await getEntries({ content_type: 'xxxxxxxx' });
  return { page: items[0] };
};

At this stage I need to make this query with the locale so I need to access Local.Consumer in the above getInitialProps. Is this possible?

Giacobo answered 14/1, 2019 at 12:10 Comment(1)
May I ask, how you solved this in the end? I am facing a very similar challenge.Margay
E
2

This does not appear to be possible according to the documentation here: https://github.com/zeit/next.js/#fetching-data-and-component-lifecycle You access React context data by wrapping your component in the context's Consumer like this:

<Locale.Consumer>
  ({locale}) => <Index locale={locale} />
</Locale.Consumer>

But getInitialProps is run for top-level pages and does not have access to the props.

Can you get your entries in another React lifecycle method, like componentDidMount? Then you could store your items in the component state.

Elka answered 1/3, 2019 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.