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
