'React throws error when using Context. Error: Element type is invalid: expected a string (for built-in components)

Error:

 Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

jsx app:

    export default function App() {
  
  let [user, setUser]:any = useState({})

  const Context:any = useContext( UserContext )

  return (<>
  <Context.Provider value={[user, setUser]}> 
    // when removing the Context.Provider everything starts working
    // but if you leave everything, then the error is also issued
    <Nav />
    <Footer />
  </Context.Provider>
  </>);  
}

context :

import { createContext } from 'react'


export const UserContext = createContext([])

index :

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

reportWebVitals();


Solution 1:[1]

That's not quite how you use useContext, which returns the value that you've associated with a provider.

You want to import the context object you exported, and use the provider from that:

import {UserContext} from './context';

function App() {
  let [user, setUser]:any = useState({});
  return ( // also don't need a fragment here
    <UserContext.Provider value={[user, setUser]}> 
      <Nav />
      <Footer />
    </UserContext.Provider>
  );
}

Then, in any component underneath your UserContext.Provider, you can call useContext to get that value:

import UserContext from './context';

function Nav() {
  const [user, setUser] = useContext(UserContext);
  ...
}

Here's a super simplistic example:

const UserContext = React.createContext([]);

function Nav() {
  const user = React.useContext(UserContext);
  
  return (
    <div>User: <code>{JSON.stringify(user)}</code></div>
  );
}

function App() {
  const [user] = React.useState({name: 'Bob'});
  return (
    <UserContext.Provider value={user}>
      <Nav />
    </UserContext.Provider>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1