Home > Software engineering >  Why is my "useContext" not defined in one component but it is in another?
Why is my "useContext" not defined in one component but it is in another?

Time:01-06

I am trying to make my sidebar only show up when a Metamaskwallet is connected, however in order to see how it works i want to replicate the way my button disappears in another component file first but i cant seem to get my useContext to work in my sidebar file.

code of sidebar:

import logo from '../../images/cryptopunk3101.png'
import { TransactionContext } from "../context/TransactionContext";

const Sidebar = () => {
    const { connectWallet, currentAccount } = useContext(TransactionContext);
    return (
        
       <nav className="w-64 flex md:justify-center justify-between items-center p-4">
          {!currentAccount && (
           <div className="sticky top-1 relative box-content h-full w-64 -left-2 -y-3 p-4 shadow-2xl list-none blue-glassmorphism text-white place-content-center content-evenly">
                <div>
                    <div className="md:flex-[o.5] flex-initial left-5 justify-center items-center">
                        <img src={logo} alt="logo" className="rounded-full border scale-75 w-full cursor-pointer" />
                        <div>
                            <h1 className='pl-5 pr-5 text-center font-bold border-b pb-2'> Digital Mirage <p className='p-1 text-center pl-8 text-white font-light md:w-9/12 w-11/12 text-base'>Developer</p></h1> 
                        <div className='object-center justify-center'>
                                <button className='w-full mt-5 mb-3 px-5 py-2 border rounded-full border-[#3d4f7c] hover:bg-[#2546bd]'>
                                Go undercover
                                </button> 
                            </div>
                            <div>
                                <button className='w-full my-3 px-5 py-2 border rounded-full border-[#3d4f7c] hover:bg-[#2546bd]'>
                                Edit profile
                                </button>
                            </div> 
                            <div>
                                <button className='w-full my-3 px-5 py-2 border rounded-full  hover:bg-[#2546bd]'>
                                Portfolio
                                </button>
                            </div> 
                                <div className='my-5'>
                                    <h1 className='font-medium'> Location: </h1> <p className='font-light'> The Netherlands</p>
                                </div>
                                <div className='my-5'>
                                    <h1 className='font-medium'> Joined on: </h1> <p className='font-light'> 4-1-2022 </p>
                                </div>
                                <div className='my-5'>
                                    <h1 className='font-medium'> Last work: </h1> <p className='font-light'> ... </p>
                                </div>
                                <div className='my-5'>
                                    <h1 className='font-medium'> Availability: </h1> <p className='font-light'> Not available </p>
                                </div>
                        </div>
                    </div>               
                </div>
            </div>)}
        </nav>
    );
}



export default Sidebar;

The code of my navbar where it seems to work for button:

import { useState } from 'react';
import { HiMenuAlt4 } from 'react-icons/hi';
import { AiOutlineClose } from 'react-icons/ai';
import { TransactionContext } from "../context/TransactionContext";
import React, { useContext } from "react";

import logo from '../../images/logo.png'

const NavbarItem = ({ title, classProps }) => {
    return (
        <li className={`mx-4 cursor-pointer ${classProps}`}>
            {title}
        </li>
        
    );
}



const Navbar = () => {
    const [toggleMenu, setToggleMenu] = useState(false);
        const { connectWallet, currentAccount } = useContext(TransactionContext);
        
        
    return (
       <nav className="w-full flex md:justify-center justify-between items-center p-4">
           <div className="md:flex-[o.5] flex-initial justify-centre items-center">
                <img src={logo} alt="logo" className="w-32 cursor-pointer" />
           </div>
           <ul className="text-white md:flex hidden list-none flex-row justify-between items-center flex-initial">
                {["Home", "Workfloor", "Explore", "DAO", "Messages", "Analytics", "Earnings", "More"].map((item, index) => (
                    <NavbarItem key={item   index} title={item} />
                ))}
                <li >
                {!currentAccount && (<button
                     type="button"
                     onClick={connectWallet}
                     className=" flex-row justify-center items-center bg-[#2952e3] p-3 my-1 rounded-full cursor-pointer hover:bg-[#2546bd]"
                    >
                    <p className="text-white text-base font-semibold">connect wallet</p>
                    </button>)}
                </li>
           </ul>
        <div className="flex relative">
            {toggleMenu
             ? <AiOutlineClose fontSize={28} className="text-white md:hidden cursor-pointer" onClick={() => setToggleMenu(false)} />
             : <HiMenuAlt4 fontSize={28} className="text-white md:hidden cursor-pointer" onClick={() => setToggleMenu(true)} /> }
            {toggleMenu && (
                <ul
                className="z-10 fixed top-0 -right-2 p-3 w-[70vw] shadow-2xl md:hidden list-none
                flex flex-col justify-start items-end rounded-md blue-glassmorphism text-white animate-slide-in
                "
                >
                    <li className="text-xl w-full my-2">
                        <AiOutlineClose onClick={() => setToggleMenu(false)} />

                    </li>
                    {["Home", "Workfloor", "Explore", "DAO", "Messages", "Analytics", "Earnings", "More"].map((item, index) => (
                        <NavbarItem key={item   index} title={item} classProps="my-2 text-lg" />
                    ))}
                </ul>
            )}      
        </div>
        </nav>
    );
}

export default Navbar;

The file where my import comes from:

import React, { useEffect, useState } from 'react';
import { ethers } from 'ethers';

import { contractABI, contractAddress } from '../utils/constants';
import { ConstructorFragment } from 'ethers/lib/utils';

export const TransactionContext = React.createContext();

const { ethereum } = window;

const getEthereumContract = () => {
    const provider = new ethers.providers.Web3Provider(ethereum);
    const signer = provider.getSigner();
    const transactionContract = new ethers.Contract(contractAddress, contractABI, signer);
  
    return transactionContract;
    
}

export const TransactionProvider = ({ children }) => {
    const [currentAccount, setCurrentAccount] = useState('');
    const [formData, setFormData] = useState({ addressTo: '', amount: '', keyword: '', message: '',});
    const [isLoading, setIsLoading] = useState(false);
    const [transactionCount, setTransactionCount] = useState(localStorage.getItem("transactionCount"));

    const handleChange = (e, name) => {
        setFormData ((prevState) => ({ ...prevState, [name]: e.target.value }));
    }
    
    const checkIfWalletIsConnected = async () => {
       try {
        if(!ethereum) return alert("please install metamask")

        const accounts = await ethereum.request({ method: 'eth_accounts'});

        if (accounts.lenght) {
            setCurrentAccount(accounts[0]);

            // get AllTransactions();
        } else{
            console.log('No accounts found');
        }
       } catch (error) {
        console.log(error)

        throw new Error("No ethereum object");
        }
    }

    const connectWallet = async () => {
        try {
          if (!ethereum) return alert("Please install MetaMask.");
    
          const accounts = await ethereum.request({ method: "eth_requestAccounts", });
    
          setCurrentAccount(accounts[0]);
        } catch (error) {
          console.log(error);
    
          throw new Error("No ethereum object");
        }
      };

    const sendTransaction = async () => {
        try {
          if (!ethereum) return alert("Please install MetaMask.");  

          const { addressTo, amount, keyword, message } = formData;
          const transactionContract = getEthereumContract();
          const parsedAmount = ethers.utils.parseEther(amount);

          await ethereum.request({
              method: 'eth_sendTransaction',
              params: [{
                  from: currentAccount,
                  to: addressTo,
                  gas: '0x5208', // 21000 gwei
                  value: parsedAmount._hex, 
              }]
          });
          
          const transactionHash = await transactionContract.addToBlockchain(addressTo, parsedAmount, message, keyword);

          setIsLoading(true);
          console.log(`Loading - ${transactionHash.hash}`);
          await transactionHash.wait();
          setIsLoading(false);
          console.log(`Succes - ${transactionHash.hash}`);

          const transactionCount = await transactionContract.getTransactionCount();
          
          setTransactionCount(transactionCount.toNumber())  
        } catch (error) {
          console.log(error);
    
          throw new Error("No ethereum object");
        }
    }

    useEffect(() => {
        checkIfWalletIsConnected();
    }, [])

    return (
        <TransactionContext.Provider value={{ connectWallet, currentAccount, formData, setFormData, handleChange, sendTransaction }}>
            {children}
        </TransactionContext.Provider>
    );
};

The error in my browser mainly points at this as the cause: Uncaught ReferenceError: useContext is not defined at Sidebar (Sidebar.jsx:11)

Any help is appreciated!

CodePudding user response:

I'm sorry if this is an obvious question but it doesn't seem like you are importing useContext in that first example or have you just left it off?

CodePudding user response:

As the comments have suggested i forgot the import React, { useContext } from "react"; line

  •  Tags:  
  • Related