axios 如何在单击React中的按钮时进行API调用

ezykj2lf  于 2022-11-05  发布在  iOS
关注(0)|答案(3)|浏览(201)

我想在单击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>
  );
}
cwtwac6a

cwtwac6a1#

只需将API调用移到一个单独的函数,比如getAPIData或makeAPICall。使用普通函数或使用useCallback来避免函数的多次创建。现在,您可以在初始加载时在useEffect中调用此函数,也可以在其他任何您希望进行相同API调用的地方调用此函数。
使用状态变量存储从API调用获得的数据并使用此变量呈现JSX元素。

const makeAPICall = () => {
    //api call and response
    //store response in a state variable
}

useEffect(()=>{ 
    makeAPICall();
}, [])

const handleClickEvent = () => {
    makeAPICall();
}
f1tvaqid

f1tvaqid2#

首先,react不允许在其他函数中重新注解或使用像useEffect这样的钩子,这就是为什么你会得到错误。现在,因为你需要点击数据,所以把你在useEffect中编写的获取代码放在ClickHandler中(你不需要上面定义的场景中的useEffect)。

const handleListItemClick = () => {
 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);
    });
}

如果你想使用这个数据,把它添加到一个状态变量中,然后使用它。

sxpgvts3

sxpgvts33#

我建议您使用reducer来处理此类操作,因此当您单击按钮时,它将在reducer中调度一个状态来执行API获取,并在页面加载到useEffect中时调度一个状态。

相关问题