StackOverflow 社区您好, 我不是前端开发人员,但目前正在尝试使用可用的 Solana Dapp Scaffold 为 Solana 应用程序构建测试前端。但是,以下代码得到
“账号采集失败!hook调用无效。只能调用hook 函数组件主体内部。这可能发生在一个人身上 原因如下: 1. 您的版本可能不匹配 React 和渲染器(例如 React DOM) 2. 你可能会破坏 Hooks 规则 3. 你可能有不止一份 React 副本 相同的应用程序 请参阅 https://reactjs.org/link/invalid-hook-call 了解提示 关于如何调试和解决这个问题。”
当我第一次使用 React 和 Solana 进行前端开发时,我正在寻求指导,尽管类似小项目的经验有限。尽管熟悉其他方法,但我发现在 React 中即使是基本任务也具有挑战性,并且集成 Solana 又增加了一层复杂性。您可以提供的任何帮助或资源都将非常有价值。预先感谢您对我们的支持! 问候, 费尔达
让PROGRAM_ABI; // 定义 PROGRAM_ABI 变量
// 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>
);
};