Retrieve chainid/contractaddress prior to render

Hi all,

I am running into the following problem. I am looking to retrieve data from a web3 array and return that data in a React frontend. I have already worked out the code to function via an onclick event and this works just fine => the problem is I would like the data to be retrieved prior to page load or at the least as the page is loading without having the user to press a button.

As I am using the functional oriented coding as opposed to object oriented coding I have used useState and useEffect to mimic the component render part. Everything seems to work out on the mounting process and all works as it should however when I try to console log out the chainId and contractaddress (which I need to retrieve the data in the array) it seems that I cannot retrieve the data and it logs NaN/Null.

As stated if I press the button to execute the same code all works well however when I try to do the same thing prior to any rendering it returns NaN/null.

The reason that I am putting my question here is that I am starting to suspect that useMoralis() somehow doesnt work prior to rendering however this is purely a gut feeling. Does anyone have any experience with this and/or can help me.

Please find code below to get a sense of the problem:

export default function App() {

// Instantiate moralis and retrieve backend contract information.
const { Moralis, isWeb3Enabled, chainId: chainIdHex } = useMoralis();
const chainId = parseInt(chainIdHex);
const threadAddress =
chainId in contractAddresses ? contractAddresses[chainId][0] : null;
const [mounted, setMounted] = useState(false);

if (!mounted) {
console.log(“Printed prior to render”);
console.log({ chainId });
console.log({ threadAddress });
}

useEffect(() => {
setMounted(true);
console.log(“mounted”);
}, []);

}

You may need to add dependencies to that use effect like is initialized and this way to call it only when everything is initialized

Correct me if I am wrong but if I am looking to log the chainId and threadAddress in the If statement wouldn’t changes to the dependencies in useEffect be redundent as the useEffect is used to start the render process?

As you might have guessed I am still quite new to this so bear with me if I come across as dense.

Thank you for helping btw

You can use dependencies in use effect and trigger that code in specific circumstances.

By default, useEffect runs both after the first render and after every update. As mentioned in the docs, you can read more in the docs on some customization.

@cryptokid/@qudusayo Yes agree, I am all clear on the usage of useeffect.

That being said I have re-read my first post and it seems that some things are getting lost in translation due to my poor explanation of the issue. The code in my first post shows that I am trying to log the chain id and threadaddress however this is an simplified illustration of what I am actually doing (I realize that I should have initialized first)…

In real terms I am running a function that should grab data from a web3 array for which I need chainId and threadaddress as input parameters. (Please find the code below). This function includes the enabling of web3 so all data should be initialized in order for the data to be fetched. When I executed this function via an onclick event it was working properly and all is well. This leads me to conclude that the code works.

The problem came in when I executed that exact same function (which was working fine) and had it execute prior to the page loading. Now it was unable to grab the parameters as it did before which I think is weird as only the timing changed.

My apologies for not clarifying this in the first post as I was skipping over some potentially relevant parts and the code in the first post is a poor representation of what I am looking for.

@cryptokid: “You may need to add dependencies to that use effect like is initialized and this way to call it only when everything is initialized” => You are correct when speaking to my first post however I was explaining my issue entirely wrong. I hope this post will help clarfify that all things should already be initialized prior to the fetching process (see ‘await Moralis.enableWeb3()’ in code). This is corroborated by the fact that the code runs fine with onclick.

“You can use dependencies in use effect and trigger that code in specific circumstances.” => Adding dependencies should not have to matter as this runs as soon as the page wants to load and at that point nothing should have been able to trigger the useEffect.

async function createnewarray() {
await Moralis.enableWeb3();
const chainId = parseInt(chainIdHex);
const threadAddress =
chainId in contractAddresses ? contractAddresses[chainId][0] : null;
console.log(“creation web3 enabled”);
console.log({ chainId });
console.log({ threadAddress });
const arraylength = parseInt(
await Moralis.executeFunction({
contractAddress: threadAddress,
functionName: “getThreadIndexLength”,
abi: abi,
params: {},
})
);
console.log(arraylength);

Thank you very much again for helping me.

Brainfart: could the difficulties arise from the fact that nothing has been rendered yet? More specifically the exclusion of a connectbutton/Metamask entry point which could act as an onramp for the reading of the chainId/contractaddresses?

Can you please read this on posting code.

the problem is I would like the data to be retrieved prior to page load

Anything that needs to be done before actual page load would need to be done serverside e.g. fetching data from an API. But in this case if you want to get the chainId from the user’s wallet, it would need to happen clientside (after page loads) - this is where you can use useEffect to run code as soon as possible based on state or any dependencies it uses.

at the least as the page is loading without having the user to press a button.

Typically this is what an empty useEffect is for (which is run when component is mounted) but you need to wait for web3 to be enabled to get the chain from the useMoralis hook. The delay with this would hardly be noticeable to users.

Can you post your full component code (formatted) and what you want to run or call.