javascriptnext.jsreact-context

TypeError: Cannot destructure property 'setAppState' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined


I am trying to set up some app context that will be needed throughout the application and seemed to have run into an error that I just cant figure out. I know there are multiple questions regarding the same error, but after looking through them all I still cant seem to solve my issue. It seems as if my appContext is undefined, but I dont understand why that would be the case?

TypeError: Cannot destructure property 'setAppState' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined.;

Here are my files:

//appContext.js

import React, { createContext } from 'react';

const AppContext = createContext();

export default AppContext;

//appReducer.js 

const AppReducer = (state, action) => {
  switch (action.type) {
    case 'SET_APP_STATE':
      return {
        ...state,
        openCities: [...action.payload.openCities],
      };

    default:
      return {
        ...state,
      };
  }
};

export default AppReducer;

//appState.js 

import React, { useMemo, useReducer } from 'react';
import AppContext from './appContext';
import AppReducer from './appReducer';

const AppState = (props) => {
  const initialState = {
    openCities: [],
  };

  const [state, dispatch] = useReducer(AppReducer, initialState);

  async function setAppState(payload) {
    dispatch({
      type: 'SET_APP_STATE',
      payload,
    });
  }

  return (
    <AppContext.Provider
      value={{
        openCities: state?.openCities,
        setAppState,
      }}
    >
      {props.children}
    </AppContext.Provider>
  );
};

export default AppState;

//setOpenCitiesContext.js

import { useContext, useEffect } from 'react';
import AppContext from '../context/appContext/appContext';
import getOpenCities from '../services/city/getOpenCities';
const setOpenCitiesContext = () => {
  const { setAppState } = useContext(AppContext);
  useEffect(() => {
    fetchOpenCities();
  }, []);

  const fetchOpenCities = async () => {
    const openCities = await getOpenCities();

    setAppState(openCities.cities);
  };
};

export default setOpenCitiesContext;

//app.js 

import React, { useEffect } from 'react';
import TagManager from 'react-gtm-module';
import '../font/font.css';
import '../styles/globals.css';
import '../fonts/fonts.css';
import '../styles/custom.css';
import { CookiesProvider } from 'react-cookie';
import AppState from '../context/appContext/appState';
import UserState from '../context/UserState';
import Amplify from 'aws-amplify';
import awsconfig from '../public/aws-exports';
import NProgress from 'nprogress';
import Router from 'next/router';
import 'nprogress/nprogress.css';
import { GiveawayBanner } from '../components/staticStorefront/GiveawayBanner';
import setOpenCitiesContext from '../utils/setOpenCitiesContext';
Amplify.configure(awsconfig);

const tagManagerArgs = {
  gtmId: 'GTM-KBTCTKD',
};

function MyApp({ Component, pageProps }) {
  setOpenCitiesContext();
  NProgress.configure({
    minimum: 0.3,
    easing: 'ease',
    speed: 800,
    showSpinner: false,
  });

  Router.events.on('routeChangeStart', () => NProgress.start());
  Router.events.on('routeChangeComplete', () => NProgress.done());
  Router.events.on('routeChangeError', () => NProgress.done());

  useEffect(() => {
    TagManager.initialize(tagManagerArgs);
  }, []);

  return (
    <CookiesProvider>
      <AppState>
        <UserState>
          {/* <GiveawayBanner /> */}
          <Component {...pageProps} />
        </UserState>
      </AppState>
    </CookiesProvider>
  );
}


Solution

  • For anyone that comes across this error the solution for me was to move my setOpenCitiesContext.js custom hook out of the app.js file (where my context provider was initiated) and move it into my index.js file. I am assuming having them in the same file (app.js) was causing react to call my custom hook which was trying to set the context before my context provider was defined (which as I am writing this out is exactly what the error was saying hahaha). Anyways hope my lapse in judgment can help someone else out down the line.

    ps. If my thoughts above are incorrect please feel free to explain why this was happening I would love to have a deeper understanding on the issue.