'failed to get data from my contract using the navbar (web3 react hooks async function)
I'm trying to build My first react Dapp! The problem I encounter is the data doesn't load only when I'm refreshing the page instead of navigating with the navbar ! for example when I navigate to profile the section using web3 doesn't load but when I refresh the page, all the data is filled correctly and all works fine here's my code of the component which is call the section using web3 (it's the profile section) :
function Home() {
const [profile, setProfile] = useState({});
const [loading, setLoading] = useState(true);
const [account, setAccounts] = useState(null);
const [contract, setContract] = useState(null);
useEffect(() => {
async function fetchData() {
try {
console.log("ok1");
const web3 = await getWeb3();
console.log("ok2");
const accounts = await web3.eth.getAccounts();
const networkId = await web3.eth.net.getId();
const deployedNetwork = CVStorageContract.networks[networkId];
const instance = new web3.eth.Contract(
CVStorageContract.abi,
deployedNetwork && deployedNetwork.address,
);
setAccounts(accounts);
setContract(instance);
const response = await instance.methods.getProfileDetails(accounts[0]).call();
setProfile(response);
} catch (error) {
// Catch any errors for any of the above operations.
alert(
`Failed to load web3, accounts, or contract. `,
);
console.error(error);
} finally {
setLoading(false)
}
}
fetchData();
});
return (
<>
{loading ? <div>Loading ... </div> : <div className="layout-content">
<Profile profile={profile} account={account} contract={contract} page="home" />
</div>}
</>
);
it stuck in loading when I navigate using the navbar and the console only show " ok1 " (which is the first console.log without any error message
and here's the getWeb3.js
import Web3 from "web3";
const getWeb3 = () =>
new Promise((resolve, reject) => {
// Wait for loading completion to avoid race conditions with web3 injection timing.
window.addEventListener("load", async () => {
// Modern dapp browsers...
if (window.ethereum) {
const web3 = new Web3(window.ethereum);
try {
// Request account access if needed
await window.ethereum.enable();
// Accounts now exposed
resolve(web3);
} catch (error) {
reject(error);
}
}
// Legacy dapp browsers...
else if (window.web3) {
// Use Mist/MetaMask's provider.
const web3 = window.web3;
console.log("Injected web3 detected.");
resolve(web3);
}
// Fallback to localhost; use dev console port by default...
else {
const provider = new Web3.providers.HttpProvider(
"http://127.0.0.1:8545"
);
const web3 = new Web3(provider);
console.log("No web3 instance injected, using Local web3.");
resolve(web3);
}
});
});
export default getWeb3;
Solution 1:[1]
I think you need pass an empty array to useEffect in your Home component to render each time that the component render, if you dont pass it, the function just execute one time
useEffect(() => {
async function fetchData() {
//...code
}
fetchData();
}, []);
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 | enzou |
