探索前端开发挑战:寻求 React 和 Solana 集成指南

问题描述 投票:0回答:1

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>
    );
};
react-native react-hooks solana
1个回答
0
投票

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>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.