我正在尝试使用React和Easybase(数据库(。然而,我遇到了一些问题。
这在SolanaSignature.tsx文件中。
import { useWallet } from '@solana/wallet-adapter-react';
import bs58 from 'bs58';
import React, { FC, useCallback } from 'react';
import ReactDOM from 'react-dom';
import { sign } from 'tweetnacl';
import AddUser from './mainstorage';
export const SignMessageButton : FC = () => {
const { publicKey, signMessage } = useWallet();
const onClick = useCallback(async () => {
try {
if (!publicKey) throw new Error('Wallet not connected!');
if (!signMessage) throw new Error('Wallet does not support message signing! Please use a wallet such as Phantom or Solflare! NOTE: Some Ledgers wallets are not supported!');
const message = new TextEncoder().encode('Omega Protocol - Signature verification for Bold Badgers.');
const signature = await signMessage(message);
if (!sign.detached.verify(message, signature, publicKey.toBytes())) throw new Error('Invalid signature!');
//alert(`Message signature: ${bs58.encode(signature)}`);
AddUser();
} catch (error: any) {
alert(`Signing failed: ${error?.message}`);
}
}, [publicKey, signMessage]);
return signMessage ? (<button className="wallet-adapter-button wallet-adapter-button-trigger shine" onClick={onClick} disabled={!publicKey}>Verify</button>) : null;
};
然后是主存储文件:
import { useEffect } from 'react';
import { useEasybase } from 'easybase-react';
const AddUser = () => {
const { db } = useEasybase();
useEffect(() => {
db('OMEGABB').insert({ walletid: "test", discordid: "test", signature: "test", valid: false, lastvalid: new Date() }).one()
.then(() => console.log("Success!"));
}, [])
return (
{/* ... */}
);
}
export default AddUser;
然而,当我单击该按钮时,会出现一个警告:钩子只能在函数组件的内部调用
这在初始索引文件(也称为父文件(中有效,但在此处不起作用。现在,这只是一个伪/测试,但正在尝试将其写入数据库。
谢谢!
根据React的文档:
不要在循环、条件或嵌套函数中调用Hook。相反,在任何早期返回之前,始终在React函数的顶层使用Hooks。
当前,您正试图在onClick
处理程序中调用一个钩子-AddUser
是一个自定义钩子,因为它也使用钩子,更好的名称应该是useAddUser
。
我建议通过从自定义挂钩返回一个函数来进行一些改进,您可以调用该函数来添加新用户,例如:
export const useAddUser = () => {
const {db} = useEasybase()
const addUser = React.useCallback(() => {
db('OMEGABB')
.insert(/*...*/)
.then(/*...*/)
.catch(/*...*/)
}, [db])
return {
addUser,
/*...*/
}
}
然后,您可以通过以下方式使用useAddUser
:
const {useAddUser} from './mainstorage'
const SignMessageButton: FC = () => {
const {publicKey, signMessage} = useWallet()
const {addUser} = useAddUser();
const onClick = React.useCallback(
async () => {
try {
// ...
addUser()
} catch (error) {/*...*/}
},
[publicKey, signMessage, addUser]
)
/*...*/
}