我想在单击Button组件时从货币API中获取数据。我已经将请求数据的代码放在了useEffect挂钩中,但是当我尝试将useEffect放在handleClickOpen函数中时,它返回了一个错误。我应该省略useEffect吗?我应该将API调用放在下面代码的什么位置?
import * as React from 'react';
import { useEffect } from "react"
import axios from "axios"
import PropTypes from 'prop-types';
import Button from '@mui/material/Button';
import Avatar from '@mui/material/Avatar';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemAvatar from '@mui/material/ListItemAvatar';
import ListItemText from '@mui/material/ListItemText';
import DialogTitle from '@mui/material/DialogTitle';
import Dialog from '@mui/material/Dialog';
import { blue } from '@mui/material/colors';
const emails = [
{title: "Pound sterling", symbol: "£", id: 1, acronym: "GBP"},
{title: "Euro", symbol: "€", id: 2, acronym: "EUR"},
{title: "Nigerian Naira", symbol: "₦", id: 3, acronym: "NGN"},
{title: "Saudi Arabian riyal", symbol: "SR", id: 4, acronym: "SAR"},
{title: "Indian rupee", symbol: "₹", id: 5, acronym: "INR"},
{title: "United States dollar", symbol: "$", id: 6, acronym: "USD"},
]
function SimpleDialog(props) {
const { onClose, selectedValue, open } = props;
const handleClose = () => {
onClose(selectedValue);
};
const handleListItemClick = (value) => {
onClose(value);
};
useEffect(() => {
const options = {
method: 'GET',
url: 'https://exchangerate-api.p.rapidapi.com/rapid/latest/USD',
headers: {
'X-RapidAPI-Key': 'c0d2e70417msh3bde3b7dbe9e25ap12748ejsncd1fe394742c',
'X-RapidAPI-Host': 'exchangerate-api.p.rapidapi.com'
}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
},[])
return (
<Dialog onClose={handleClose} open={open}>
<DialogTitle>Choose a currency</DialogTitle>
<List sx={{ pt: 0 }}>
{emails.map((email) => (
<ListItem button onClick={() => handleListItemClick(email.symbol)} key={email.id}>
<ListItemAvatar>
<Avatar sx={{ bgcolor: blue[100], color: blue[600] }}>
{email.symbol}
</Avatar>
</ListItemAvatar>
<ListItemText primary={email.title} />
</ListItem>
))}
</List>
</Dialog>
);
}
SimpleDialog.propTypes = {
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
selectedValue: PropTypes.string.isRequired,
};
export default function SimpleDialogDemo({selectedValue, setSelectedValue}) {
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = (value) => {
setOpen(false);
setSelectedValue(value);
};
return (
<div>
<Button variant="text" onClick={handleClickOpen} sx={{
ml: 30,
mb: 0,
p: 0,
}}>
{selectedValue} {emails.find(email => email.symbol===selectedValue).acronym}
</Button>
<SimpleDialog
selectedValue={selectedValue}
open={open}
onClose={handleClose}
/>
</div>
);
}
3条答案
按热度按时间cwtwac6a1#
只需将API调用移到一个单独的函数,比如getAPIData或makeAPICall。使用普通函数或使用useCallback来避免函数的多次创建。现在,您可以在初始加载时在useEffect中调用此函数,也可以在其他任何您希望进行相同API调用的地方调用此函数。
使用状态变量存储从API调用获得的数据并使用此变量呈现JSX元素。
f1tvaqid2#
首先,react不允许在其他函数中重新注解或使用像useEffect这样的钩子,这就是为什么你会得到错误。现在,因为你需要点击数据,所以把你在useEffect中编写的获取代码放在ClickHandler中(你不需要上面定义的场景中的useEffect)。
如果你想使用这个数据,把它添加到一个状态变量中,然后使用它。
sxpgvts33#
我建议您使用reducer来处理此类操作,因此当您单击按钮时,它将在reducer中调度一个状态来执行API获取,并在页面加载到useEffect中时调度一个状态。