我不是前端开发人员,但目前正在尝试使用可用的 Solana Dapp 支架为 Solana 应用程序构建测试前端。但是,我有以下错误:
“账号采集失败!hook调用无效。只能调用hook 函数组件主体内部。这可能发生在一个人身上 原因如下: 1. 您的版本可能不匹配 React 和渲染器(例如 React DOM) 2. 你可能会破坏 Hooks 规则 3. 你可能有不止一份 React 副本 相同的应用程序 请参阅 https://reactjs.org/link/invalid-hook-call 了解提示 关于如何调试和解决这个问题。”
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>
);
};
onClick
回调调用useWallet
,这违反了React的Hooks规则之一。你不应该在嵌套函数/回调/等中调用 React hooks。
使用外部作用域中的
useWallet
访问 publicKey
、signTransaction
和 signAllTransactions
值,确保这些值正确添加到 useCallback
钩子的依赖项数组中。
export const GetContractAccounts: FC = () => {
const { connection } = useConnection();
const {
publicKey,
signTransaction,
signAllTransactions
} = useWallet();
...
const onClick = useCallback(async () => {
if (!publicKey) {
...
}
...
try {
...
const signerWallet = {
publicKey,
signTransaction,
signAllTransactions,
};
const provider = new anchor.Provider(
connection,
signerWallet,
{ commitment: "processed" }
);
...
} catch (error: any) {
...
}
}, [publicKey, signTransaction, signAllTransactions, connection]);
return (
<div className="flex flex-row justify-center">
<div className="relative group items-center">
<div className="....." />
<button className="...." onClick={onClick}>
<span>Contract Accounts</span>
</button>
</div>
</div>
);
};