Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access React context outside of component

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?

like image 382
CaribouCode Avatar asked Jan 14 '19 12:01

CaribouCode


1 Answers

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.

like image 87
Gordon Burgett Avatar answered Sep 21 '22 07:09

Gordon Burgett