Search code examples
reactjsreact-hooksuse-context

useContext React not defined


I am trying to build a simple React App with some CRUD connected to a Rails API. The structure of the project is this:

App.js
 -> UserIndex
   --> Form
   --> User
 -> User

I want to send a value (a function) from <App /> to its grandchild (NOT the immediate child) <User />.

This is <App />:

import "./App.css";
import User from "./components/User";
import UserIndex from "./components/UserIndex";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { useState, createContext } from "react";

function App() {
  const [user, setUser] = useState({});
  const UserContext = createContext();

  function handleShow() {
    console.log("showed!");
  }

  return (
    <div>
      <BrowserRouter>
        <Routes>
          <UserContext.Provider value={handleShow}>
            <Route path="/" element={<UserIndex />}></Route>
          </UserContext.Provider>
          <Route
            path="users/:userId"
            element={<User id={user.id} name={user.name} email={user.email} />}
          />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;

I imported CreateContext and created it and also provided it with UserContext.Provider.

And this is the <User />:

import React, { useContext } from "react";
import { Link } from "@mui/material";
import axios from "axios";

function User(props) {
  const userName = useContext(UserContext);
  return (
    <div className="centerText">
      <Link
        href={`/users/${props.id}`}
        color="inherit"
        onClick={props.handleShow}
      >
        <h4>{props.name}</h4>
        <h4>{props.email}</h4>
      </Link>
      {props.deleteData && <button onClick={props.deleteData}>Delete</button>}
    </div>
  );
}

export default User;

I imported useContext and I am trying to get the UserContext that I provided but it doesn´t work. It says: userContext is not defined.

Tried also wrapping everything on the UserContext.Provider like this:

<BrowserRouter>
        <Routes>
          <UserContext.Provider value={handleShow}>
            <Route path="/" element={<UserIndex />}></Route>

            <Route
              path="users/:userId"
              element={
                <User id={user.id} name={user.name} email={user.email} />
              }
            />
          </UserContext.Provider>
        </Routes>
      </BrowserRouter>

But it doesnt work either. I searched on the Internet but all the examples are in the same .js file so there is no problem fetching the UserContext

What am I doing wrong? Thanks!

EDIT:

After following the corrections this is how it looks now.

import "./App.css";
import User from "./components/User";
import UserIndex from "./components/UserIndex";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { useState, createContext } from "react";

export const UserContext = createContext();

function App() {
  const [user, setUser] = useState({});

  // function handleShow() {
  //   console.log("showed!");
  // }
  const handleShow = "fñalksdjfñdlskfjds";

  return (
    <div>
      <BrowserRouter>
        <Routes>
          <Route
            path="/"
            element={
              <UserContext.Provider value={handleShow}>
                <UserIndex />
              </UserContext.Provider>
            }
          ></Route>

          <Route
            path="users/:userId"
            element={<User id={1} name={"hey"} email={"there"} />}
          />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;
import React, { useContext } from "react";
import { Link } from "@mui/material";
import axios from "axios";
import UserContext from "../App";

function User(props) {
  console.log(UserContext);
  const userName = useContext(UserContext);

  console.log(userName);

  return (
    <div className="centerText">
      <Link
        href={`/users/${props.id}`}
        color="inherit"
        onClick={props.handleShow}
      >
        <h4>{props.name}</h4>
        <h4>{props.email}</h4>
      </Link>
      {props.deleteData && <button onClick={props.deleteData}>Delete</button>}
    </div>
  );
}

export default User;


Solution

  • Declare & export UserContext outside App.

    export const UserContext = createContext();
    
    function App() {
    ...
    

    Then

    import { UserContext } from '/App';