React 和 Easybase - 无效挂钩调用。钩子只能在函数组件的内部调用
React and Easybase - Invalid hook call. Hooks can only be called inside of the body of a function component
我正在尝试使用 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;
但是,当我单击该按钮时,会出现一个警告:Hooks can only be called inside of a function component.
这在初始索引文件(又名父文件)中有效,但在此处无效。现在这只是一个 dummy/test 但试图让它写入数据库。
谢谢!
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns.
目前,您正试图在 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]
)
/*...*/
}
我正在尝试使用 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;
但是,当我单击该按钮时,会出现一个警告:Hooks can only be called inside of a function component.
这在初始索引文件(又名父文件)中有效,但在此处无效。现在这只是一个 dummy/test 但试图让它写入数据库。
谢谢!
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns.
目前,您正试图在 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]
)
/*...*/
}