I am not a frontend developer but currently trying to construct a test frontend for Solana app using the available Solana Dapp Scaffold. However, I have the following error:
"Account gathering failed! Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem."
let PROGRAM_ABI; // Define PROGRAM_ABI variable
// Fetch the JSON file using fetch API
fetch('../deployment_data/xxx.json')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json(); // Parse the JSON response
})
.then(data => {
// Assign the parsed JSON data to PROGRAM_ABI
PROGRAM_ABI = data;
console.log('PROGRAM_ABI:', PROGRAM_ABI);
})
.catch(error => {
console.error('Error fetching JSON:', error);
});
export const GetContractAccounts: FC = () => {
const { connection } = useConnection();
const { publicKey } = useWallet();
const { getUserSOLBalance } = useUserSOLBalanceStore();
const onClick = useCallback(async () => {
if (!publicKey) {
console.log('error', 'Wallet not connected!');
notify({
type: 'error',
message: 'error',
description: 'Wallet not connected!'
});
return;
}
let signature: TransactionSignature = '';
try {
const secret = [my private key]; // Replace with your secret
const fromKeypair = Keypair.fromSecretKey(new Uint8Array(secret));
const communityId = 123;
const communityName = "MyCommunity";
const parentCommunityId = 456;
const tags = [];
const chainID = 789;
const chainName = "Solana";
const dataArray = [
communityId.toString(),
communityName.toString(),
parentCommunityId.toString(),
tags.join(','),
chainID.toString(),
chainName.toString()
];
const concatenatedData = dataArray.join('');
const { publicKey, signTransaction, signAllTransactions } = useWallet();
const signerWallet = {
publicKey: publicKey,
signTransaction: signTransaction,
signAllTransactions: signAllTransactions,
};
const provider = new anchor.Provider(
connection,
signerWallet,
{ commitment: "processed" }
);
const votingProgram = new PublicKey('my public key');
const program = new anchor.Program(
PROGRAM_ABI,
votingProgram,
provider
);
const accounts = await program
.account
.votingProgram
.fetch(fromKeypair.publicKey)
console.log(accounts)
} catch (error: any) {
notify({
type: 'error',
message: `Account gathering failed!`,
description: error?.message,
txid: signature
});
console.log(
'error',
`Account gathering failed! ${error?.message}`,
signature
);
}
}, [publicKey, connection]);
return (
<div className="flex flex-row justify-center">
<div className="relative group items-center">
<div
className="m-1 absolute -inset-0.5 bg-gradient-to-r
from-indigo-500 to-fuchsia-500 rounded-lg blur opacity-20
group-hover:opacity-100 transition duration-1000
group-hover:duration-200 animate-tilt"
></div>
<button
className="px-8 m-2 btn animate-pulse bg-gradient-to-br
from-indigo-500 to-fuchsia-500 hover:from-white
hover:to-purple-300 text-black"
onClick={onClick}
>
<span>Contract Accounts</span>
</button>
</div>
</div>
);
};
The
onClickcallback callsuseWalletwhich breaks one of React's Rules of Hooks. You should not call React hooks in nested functions/callbacks/etc.Use the
useWalletin the outer scope to access thepublicKey,signTransaction, andsignAllTransactionsvalues, ensuring these are properly added to theuseCallbackhook's dependency array.