获取中的 React 函数
React function inside a fetching
我列出了一个包含很多行的 table,我想根据 {transaction.to_address} 值
在每一行中使用一个新函数
我想在抓取函数中使用 useeffect() 函数,但我收到以下错误消息:
渲染了比之前渲染更多的钩子。
我已经尝试了很多我在这里找到的解决方案,我花了将近一整天的时间,但我不够聪明,无法修复它。
export default function Transactions({user}){
const Web3Api = useMoralisWeb3Api()
const [transactions, setTransactions] = useState()
const BASE_URL = "https://bscscan.com/tx/"
const fetchTransactions = async () => {
const data = await Web3Api.account.getTransactions({
chain: "bsc",
address: user.get('wallet2')
})
if(data) {
setTransactions(data.result)
}
}
useEffect(() => {
fetchTransactions()
}, [])
return(
<TableContainer>
<Table variant='simple'>
<TableCaption>TRANSACTIONS</TableCaption>
<Thead>
<Tr>
<Th>#</Th>
<Th>TYPE</Th>
<Th>GAS</Th>
<Th>VALUE</Th>
<Th>4</Th>
<Th>5</Th>
<Th>Value</Th>
</Tr>
</Thead>
<Tbody>
{transactions && transactions.map(transaction => (
transaction.value >= 1 ?
<Tr key={transaction.hash}>
<Th><Link href={`${BASE_URL}${transaction.hash}`} isExternal> {transaction.nonce}</Link></Th>
<Th>TRANS{transaction.block_timestamp}</Th>
<Th>{transaction.receipt_gas_used * Moralis.Units.FromWei(transaction.gas_price)} BNB</Th>
<Th>{Moralis.Units.FromWei(transaction.value)} BNB</Th>
<Th>{transaction.block_timestamp}</Th>
<Th>
{
useEffect(() => {
const url = "https://api.bscscan.com/api?module=contract&action=getsourcecode&address={transaction.to_address}&apikey=EEFI13SBM525DZ5ZNMBZHFEMVIT39DZA26";
const fetchData = async () => {
const response = await fetch(url)
const json = await response.json()
}
fetchData()
}, [])
}
</Th>
<Th><Link href={`${BASE_URL}${transaction.hash}`} isExternal> {transaction.hash}</Link></Th>
</Tr>
: null))}
</Tbody>
</Table>
</TableContainer>
)
}
这与我的问题类似,但对我不起作用
首先,我认为在 html 代码中间使用 useEffect 钩子不是一个好习惯,useEffect 应该总是在 return 之前调用。 Read more here。其次,您应该考虑这种方法是否有用,因为在 for 循环中获取数据可能会给您的服务器带来很大的负载(这取决于您有多少事务以及您发送了多少请求every-time)。
useEffect 用于在页面加载时获取数据,或者您可以向其放置参数,以便在参数更改时再次运行代码。不用useEffect也可以获取数据。
由于我无法复制您的代码,请自行尝试运行。
export default function Transactions({ user }) {
const Web3Api = useMoralisWeb3Api();
const [transactions, setTransactions] = useState();
const [transaction, setTransaction] = useState();
const [finished, setFinished] = useState(false);
const BASE_URL = "https://bscscan.com/tx/";
const fetchTransactions = async () => {
const data = await Web3Api.account.getTransactions({
chain: "bsc",
address: user.get("wallet2"),
});
if (data) {
setTransactions(data.result);
setFinished(true);
}
};
useEffect(() => {
if (finished && transactions) {
let list = [];
Promise.all(
transactions.map(async (transaction) => {
const API = `https://api.bscscan.com/api?module=contract&action=getsourcecode&address=${transaction.to_address}&apikey=EEFI13SBM525DZ5ZNMBZHFEMVIT39DZA26`;
const data = await fetch(API);
if (data) {
list.push(data);
}
})
);
setTransaction(list);
setFinished(true);
}
}, [finished]);
return (
<TableContainer>
<Table variant="simple">
<TableCaption>TRANSACTIONS</TableCaption>
<Thead>
<Tr>
<Th>#</Th>
<Th>TYPE</Th>
<Th>GAS</Th>
<Th>VALUE</Th>
<Th>4</Th>
<Th>5</Th>
<Th>Value</Th>
</Tr>
</Thead>
<Tbody>
{transactions &&
transactions.map((transaction, index) =>
transaction.value >= 1 ? (
<Tr key={transaction.hash}>
<Th>
<Link href={`${BASE_URL}${transaction.hash}`} isExternal>
{" "}
{transaction.nonce}
</Link>
</Th>
<Th>TRANS{transaction.block_timestamp}</Th>
<Th>
{transaction.receipt_gas_used *
Moralis.Units.FromWei(transaction.gas_price)}{" "}
BNB
</Th>
<Th>{Moralis.Units.FromWei(transaction.value)} BNB</Th>
<Th>{transaction.block_timestamp}</Th>
<Th>{transaction[index].ContractName}</Th>
<Th>
<Link href={`${BASE_URL}${transaction.hash}`} isExternal>
{" "}
{transaction.hash}
</Link>
</Th>
</Tr>
) : null
)}
</Tbody>
</Table>
</TableContainer>
);
}
我没有测试就试过了,所以请告诉我:
export default function Transactions({user}){
const Web3Api = useMoralisWeb3Api()
const [transactions, setTransactions] = useState(null)
const [transactionsAddress,setTransactionsAddress]= useState(null)
const BASE_URL = "https://bscscan.com/tx/"
const fetchTransactions = async () => {
const data = await Web3Api.account.getTransactions({
chain: "bsc",
address: user.get('wallet2')
})
if(data) {
setTransactions(data.result)
}
}
const fetchData = useCallBack(async (myUrl) => {
const response = await fetch(myUrl)
const json = await response.json()
return json},
[]);
useEffect(() => {
fetchTransactions()
}, [])
useEffect(() => {
transactions ?? (async ()=>{
let url=""
const fetchTransationsAddress= await Promise.all(transactions.map(async (transaction) => {
url = `https://api.bscscan.com/api?module=contract&action=getsourcecode&address=${transaction.to_address}&apikey=EEFI13SBM525DZ5ZNMBZHFEMVIT39DZA26`;
return await fetchData(url);
}));
setTransactionsAddress(fetchTransationsAddress);
})
}, [transactions])
return(
<TableContainer>
<Table variant='simple'>
<TableCaption>TRANSACTIONS</TableCaption>
<Thead>
<Tr>
<Th>#</Th>
<Th>TYPE</Th>
<Th>GAS</Th>
<Th>VALUE</Th>
<Th>4</Th>
<Th>5</Th>
<Th>Value</Th>
</Tr>
</Thead>
<Tbody>
{transactions && transactions.map((transaction,index) => (
transaction.value >= 1 ?
<Tr key={transaction.hash}>
<Th><Link href={`${BASE_URL}${transaction.hash}`} isExternal> {transaction.nonce}</Link></Th>
<Th>TRANS{transaction.block_timestamp}</Th>
<Th>{transaction.receipt_gas_used * Moralis.Units.FromWei(transaction.gas_price)} BNB</Th>
<Th>{Moralis.Units.FromWei(transaction.value)} BNB</Th>
<Th>{transaction.block_timestamp}</Th>
<Th>
{
//map here in your address, for example
transactionsAddress[index] && transactionsAddress[index].map((address) =>{return(<Td>{address}</Td>)})}
</Th>
<Th><Link href={`${BASE_URL}${transaction.hash}`} isExternal> {transaction.hash}</Link></Th>
</Tr>
: null))}
</Tbody>
</Table>
</TableContainer>
)
}
对于您的测试,请像这样简化您的代码:
export default function Transactions({user}){
const Web3Api = useMoralisWeb3Api()
const [transactions, setTransactions] = useState(null)
const [transactionsAddress,setTransactionsAddress]= useState(null)
const BASE_URL = "https://bscscan.com/tx/"
const fetchTransactions = async () => {
console.log('fetchTransactions');
const data = await Web3Api.account.getTransactions({
chain: "bsc",
address: user.get('wallet2')
})
if(data) {
setTransactions(data.result)
}
}
const fetchData = useCallBack(async (myUrl) => {
console.log('callback fetchdata')
const response = await fetch(myUrl)
const json = await response.json()
return json},
[]);
useEffect(() => {
console.log('useEffect 1');
fetchTransactions()
}, [])
useEffect(() => {
console.log('useEffect 2');
if (transactions!==null){
(async ()=>{
let url="";
console.log('async function inside useEffect2')
const fetchTransationsAddress= await Promise.all(transactions.map(async (transaction) => {
url = `https://api.bscscan.com/api?module=contract&action=getsourcecode&address=${transaction.to_address}&apikey=EEFI13SBM525DZ5ZNMBZHFEMVIT39DZA26`;
return await fetchData(url);
}));
setTransactionsAddress(fetchTransationsAddress);
})();
}}, [transactions,fetchData])
console.log(transactions)
console.log(transactionsAddress)
return(<div>Go to your console</div>
)}
并且知道自己找找问题,可以加一些console.log("what you want")来理解。您还需要检查您的 API 呼叫是否正在返回数据(取决于您的订阅,您可能受到限制)
我列出了一个包含很多行的 table,我想根据 {transaction.to_address} 值
在每一行中使用一个新函数我想在抓取函数中使用 useeffect() 函数,但我收到以下错误消息: 渲染了比之前渲染更多的钩子。 我已经尝试了很多我在这里找到的解决方案,我花了将近一整天的时间,但我不够聪明,无法修复它。
export default function Transactions({user}){
const Web3Api = useMoralisWeb3Api()
const [transactions, setTransactions] = useState()
const BASE_URL = "https://bscscan.com/tx/"
const fetchTransactions = async () => {
const data = await Web3Api.account.getTransactions({
chain: "bsc",
address: user.get('wallet2')
})
if(data) {
setTransactions(data.result)
}
}
useEffect(() => {
fetchTransactions()
}, [])
return(
<TableContainer>
<Table variant='simple'>
<TableCaption>TRANSACTIONS</TableCaption>
<Thead>
<Tr>
<Th>#</Th>
<Th>TYPE</Th>
<Th>GAS</Th>
<Th>VALUE</Th>
<Th>4</Th>
<Th>5</Th>
<Th>Value</Th>
</Tr>
</Thead>
<Tbody>
{transactions && transactions.map(transaction => (
transaction.value >= 1 ?
<Tr key={transaction.hash}>
<Th><Link href={`${BASE_URL}${transaction.hash}`} isExternal> {transaction.nonce}</Link></Th>
<Th>TRANS{transaction.block_timestamp}</Th>
<Th>{transaction.receipt_gas_used * Moralis.Units.FromWei(transaction.gas_price)} BNB</Th>
<Th>{Moralis.Units.FromWei(transaction.value)} BNB</Th>
<Th>{transaction.block_timestamp}</Th>
<Th>
{
useEffect(() => {
const url = "https://api.bscscan.com/api?module=contract&action=getsourcecode&address={transaction.to_address}&apikey=EEFI13SBM525DZ5ZNMBZHFEMVIT39DZA26";
const fetchData = async () => {
const response = await fetch(url)
const json = await response.json()
}
fetchData()
}, [])
}
</Th>
<Th><Link href={`${BASE_URL}${transaction.hash}`} isExternal> {transaction.hash}</Link></Th>
</Tr>
: null))}
</Tbody>
</Table>
</TableContainer>
)
}
这与我的问题类似,但对我不起作用
首先,我认为在 html 代码中间使用 useEffect 钩子不是一个好习惯,useEffect 应该总是在 return 之前调用。 Read more here。其次,您应该考虑这种方法是否有用,因为在 for 循环中获取数据可能会给您的服务器带来很大的负载(这取决于您有多少事务以及您发送了多少请求every-time)。
useEffect 用于在页面加载时获取数据,或者您可以向其放置参数,以便在参数更改时再次运行代码。不用useEffect也可以获取数据。
由于我无法复制您的代码,请自行尝试运行。
export default function Transactions({ user }) {
const Web3Api = useMoralisWeb3Api();
const [transactions, setTransactions] = useState();
const [transaction, setTransaction] = useState();
const [finished, setFinished] = useState(false);
const BASE_URL = "https://bscscan.com/tx/";
const fetchTransactions = async () => {
const data = await Web3Api.account.getTransactions({
chain: "bsc",
address: user.get("wallet2"),
});
if (data) {
setTransactions(data.result);
setFinished(true);
}
};
useEffect(() => {
if (finished && transactions) {
let list = [];
Promise.all(
transactions.map(async (transaction) => {
const API = `https://api.bscscan.com/api?module=contract&action=getsourcecode&address=${transaction.to_address}&apikey=EEFI13SBM525DZ5ZNMBZHFEMVIT39DZA26`;
const data = await fetch(API);
if (data) {
list.push(data);
}
})
);
setTransaction(list);
setFinished(true);
}
}, [finished]);
return (
<TableContainer>
<Table variant="simple">
<TableCaption>TRANSACTIONS</TableCaption>
<Thead>
<Tr>
<Th>#</Th>
<Th>TYPE</Th>
<Th>GAS</Th>
<Th>VALUE</Th>
<Th>4</Th>
<Th>5</Th>
<Th>Value</Th>
</Tr>
</Thead>
<Tbody>
{transactions &&
transactions.map((transaction, index) =>
transaction.value >= 1 ? (
<Tr key={transaction.hash}>
<Th>
<Link href={`${BASE_URL}${transaction.hash}`} isExternal>
{" "}
{transaction.nonce}
</Link>
</Th>
<Th>TRANS{transaction.block_timestamp}</Th>
<Th>
{transaction.receipt_gas_used *
Moralis.Units.FromWei(transaction.gas_price)}{" "}
BNB
</Th>
<Th>{Moralis.Units.FromWei(transaction.value)} BNB</Th>
<Th>{transaction.block_timestamp}</Th>
<Th>{transaction[index].ContractName}</Th>
<Th>
<Link href={`${BASE_URL}${transaction.hash}`} isExternal>
{" "}
{transaction.hash}
</Link>
</Th>
</Tr>
) : null
)}
</Tbody>
</Table>
</TableContainer>
);
}
我没有测试就试过了,所以请告诉我:
export default function Transactions({user}){
const Web3Api = useMoralisWeb3Api()
const [transactions, setTransactions] = useState(null)
const [transactionsAddress,setTransactionsAddress]= useState(null)
const BASE_URL = "https://bscscan.com/tx/"
const fetchTransactions = async () => {
const data = await Web3Api.account.getTransactions({
chain: "bsc",
address: user.get('wallet2')
})
if(data) {
setTransactions(data.result)
}
}
const fetchData = useCallBack(async (myUrl) => {
const response = await fetch(myUrl)
const json = await response.json()
return json},
[]);
useEffect(() => {
fetchTransactions()
}, [])
useEffect(() => {
transactions ?? (async ()=>{
let url=""
const fetchTransationsAddress= await Promise.all(transactions.map(async (transaction) => {
url = `https://api.bscscan.com/api?module=contract&action=getsourcecode&address=${transaction.to_address}&apikey=EEFI13SBM525DZ5ZNMBZHFEMVIT39DZA26`;
return await fetchData(url);
}));
setTransactionsAddress(fetchTransationsAddress);
})
}, [transactions])
return(
<TableContainer>
<Table variant='simple'>
<TableCaption>TRANSACTIONS</TableCaption>
<Thead>
<Tr>
<Th>#</Th>
<Th>TYPE</Th>
<Th>GAS</Th>
<Th>VALUE</Th>
<Th>4</Th>
<Th>5</Th>
<Th>Value</Th>
</Tr>
</Thead>
<Tbody>
{transactions && transactions.map((transaction,index) => (
transaction.value >= 1 ?
<Tr key={transaction.hash}>
<Th><Link href={`${BASE_URL}${transaction.hash}`} isExternal> {transaction.nonce}</Link></Th>
<Th>TRANS{transaction.block_timestamp}</Th>
<Th>{transaction.receipt_gas_used * Moralis.Units.FromWei(transaction.gas_price)} BNB</Th>
<Th>{Moralis.Units.FromWei(transaction.value)} BNB</Th>
<Th>{transaction.block_timestamp}</Th>
<Th>
{
//map here in your address, for example
transactionsAddress[index] && transactionsAddress[index].map((address) =>{return(<Td>{address}</Td>)})}
</Th>
<Th><Link href={`${BASE_URL}${transaction.hash}`} isExternal> {transaction.hash}</Link></Th>
</Tr>
: null))}
</Tbody>
</Table>
</TableContainer>
)
}
对于您的测试,请像这样简化您的代码:
export default function Transactions({user}){
const Web3Api = useMoralisWeb3Api()
const [transactions, setTransactions] = useState(null)
const [transactionsAddress,setTransactionsAddress]= useState(null)
const BASE_URL = "https://bscscan.com/tx/"
const fetchTransactions = async () => {
console.log('fetchTransactions');
const data = await Web3Api.account.getTransactions({
chain: "bsc",
address: user.get('wallet2')
})
if(data) {
setTransactions(data.result)
}
}
const fetchData = useCallBack(async (myUrl) => {
console.log('callback fetchdata')
const response = await fetch(myUrl)
const json = await response.json()
return json},
[]);
useEffect(() => {
console.log('useEffect 1');
fetchTransactions()
}, [])
useEffect(() => {
console.log('useEffect 2');
if (transactions!==null){
(async ()=>{
let url="";
console.log('async function inside useEffect2')
const fetchTransationsAddress= await Promise.all(transactions.map(async (transaction) => {
url = `https://api.bscscan.com/api?module=contract&action=getsourcecode&address=${transaction.to_address}&apikey=EEFI13SBM525DZ5ZNMBZHFEMVIT39DZA26`;
return await fetchData(url);
}));
setTransactionsAddress(fetchTransationsAddress);
})();
}}, [transactions,fetchData])
console.log(transactions)
console.log(transactionsAddress)
return(<div>Go to your console</div>
)}
并且知道自己找找问题,可以加一些console.log("what you want")来理解。您还需要检查您的 API 呼叫是否正在返回数据(取决于您的订阅,您可能受到限制)