【问题标题】:How to open React Material-UI modal and populate with Ajax call upon clicking button?如何在单击按钮时打开 React Material-UI 模式并使用 Ajax 调用填充?
【发布时间】:2021-11-19 00:19:24
【问题描述】:

试图搜索类似的问题,但找不到任何问题,如果我错过了,请道歉。我正在使用 React Material-UI 创建一个简单的 Web 应用程序。我有一个 XGrid,它列出了用户选择的日期范围内的许多产品和各种统计数据。每行都有一个用户可以单击的按钮。这个想法是,单击按钮后,应用程序调用 API 以获取有关该行中产品的相关信息。我希望从 API 返回的信息显示在 Material-UI 模式上。

我不知道如何将信息从 API 传递到 Modal 组件并显示它。我在下面的代码中有一个简单的例子,它接近我想要完成的。

import "./styles.css";
import React from "react";
import { Button, Modal, Typography, Box } from "@material-ui/core";

export default function App() {
  const [open, setOpen] = React.useState(false);
  const handleClose = () => setOpen(false);
  
  return (
    <div className="App">
      <Button
        variant="outlined"
        color="primary"
        onClick={() => {
          setOpen(true);
          (async () => {
            let response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
            let apiCall = await response.json();
            let grouped_data = JSON.parse(apiCall.data);
          })();
        }}
      >
        Click Here
      </Button>
      <Modal open={open} onClose={handleClose}>
        <Box>
          <Typography>Random Text</Typography>
        </Box>
      </Modal>
    </div>
  );
}

在此示例中,我将代码隔离到代码沙箱上的一个 App.js 中。但是,在实践中,我会将 Button 和 Modal 组合到一个单独的组件文件中,并将 API URL 作为 prop 传递给组件。我还使用 JSONPlaceholder 而不是我的实际 API。目前,该按钮显示一个模式,上面写着“随机文本”。但是,我希望它显示使用 fetch 调用检索到的信息。

此外,该表将有数千行,因此我想避免在用户实际单击按钮之前调用 API。这样,每次有人加载页面时,我就不会使用数千个单独的 API 调用使服务器过载。感谢任何人提供的任何帮助。

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    您最好创建一个变量来保存从 api 检索到的信息,以及一个从按钮单击中调用的通用函数。像这样的:

    import "./styles.css";
    import React from "react";
    import { Button, Modal, Typography, Box } from "@material-ui/core";
    
    export default function App() {
      const [open, setOpen] = React.useState(false);
      const [data, setData] = React.useState(null);
    
      const handleClose = () => {
        setOpen(false);
        setData(null);
      };
    
      const getData = async (someID) => {
        try {
          let response = await fetch(
            `https://jsonplaceholder.typicode.com/todos/${someID}`
          );
          let apiCall = await response.json();
          let grouped_data = JSON.parse(apiCall.data);
          setOpen(true);
          setData(grouped_data);
        } catch (error) {
          //Handle errors
        }
      };
    
      return (
        <div className="App">
          <Button
            variant="outlined"
            color="primary"
            onClick={() => {
              getData(someID);
            }}
          >
            Click Here
          </Button>
          <Modal open={open} onClose={handleClose}>
            <Box>
              <Typography>{data ? data.some_property : ''}</Typography>
            </Box>
          </Modal>
        </div>
      );
    }
    

    【讨论】:

    • 我很欣赏 Kieran 的回复,非常聪明的解决方案。我遇到的唯一问题是在例如使用这个解决方案。代码框,当我单击按钮时,模式不会弹出打开。不确定这是否与我有关,但我认为这是因为 setOpen 和 setData 是在异步函数中设置的。有关如何处理此问题的任何建议?
    • 你有codeandbox的链接吗
    • 很遗憾我没有,因为我没有帐户。正要下班吃午饭,所以我会在之后设置一个并在此评论中放置一个链接。否则,我所做的只是启动一个 React 代码框,添加 @material-ui/core 作为依赖项,然后复制并粘贴您的代码(并将 getData(someID) 更改为 getData(1),还尝试了 getData("1") )。
    • 好的,该链接适用于 grouped_data 的硬编码值。但是当我尝试切换到进行 API 调用时,它不再起作用了。不知道发生了什么。
    • 没关系,我只需要调整处理 JSON 有效负载的方式。将您的方法改编到我正在从事的项目中,并且效果很好。非常感谢您的帮助,我会将您的回复标记为已接受的答案。祝你有美好的一天!
    猜你喜欢
    • 2020-12-28
    • 1970-01-01
    • 2023-01-31
    • 2023-03-14
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    相关资源
    最近更新 更多