从React Functional组件进行API调用

如何解决从React Functional组件进行API调用

我是React的新手,我了解Functional和Class组件的概念以及诸如Hooks的钩子,例如useEffect和useState;因此,当我在下面的React组件上工作时,我很难将这些知识付诸实践。该组件可以进行简单的Javascript API调用,现在我想使用State和Hooks转换为“真正的” React API Call。>

我的问题如下:我想呈现API返回的雇员对象,从雇员的名字和姓氏开始,然后是其他信息。

使用纯Javascript对API的请求进行得很好,并返回了所需的数据;因此,我不确定如何根据定义将状态设置为什么(0,否?还有其他内容?取决于什么,我怎么知道?)。

这是代码:

import React,{useEffect,useState} from 'react';
import { Link } from "react-router-dom";
import {
    Container,Row,Col,Card,CardBody,Table,Button,Alert,Modal,ModalHeader,ModalBody
} from "reactstrap";


const ContactsList = (props) => {

        let request = new XMLHttpRequest()

        // Open a new connection,using the GET request on the URL endpoint
        request.open('GET','https://somenet.net/employee',true)

        request.onload = function () {
            // Begin accessing JSON data here
            let data = JSON.parse(this.response)

           data.forEach((employee) => {
                // Log each movie's title
                console.log(employee.id,employee.firstname,employee.lastname,employee.performance_index,employee.min_customer_distance,employee.customer_distance_radius,employee.webfleet_obj_id,employee.default_employee_working_schedule_id)
            })
        }
        // Send request
        request.send()

        let employees = [


            {
                id: 1,img: "Null",name: "David McHenry",designation: "UI/UX Designer",email: "david@skote.com",projects: "125",skills: [
                    { name: "Photoshop" },{ name: "illustrator" }
                ]
            }
        ]

       const users = [
            {
                id: 1,{ name: "illustrator" }
                ]
            },{
                id: 2,img: avatar2,name: "Frank Kirk",designation: "Frontend Developer",email: "frank@skote.com",projects: "132",skills: [
                    { name: "Html" },{ name: "Css" },{ name: "2 + more" },]
            },{
                id: 3,img: avatar3,name: "Rafael Morales",designation: "Backend Developer",email: "Rafael@skote.com",projects: "1112",skills: [
                    { name: "Php" },{ name: "Java" },{ name: "Python" },{
                id: 4,name: "Mark Ellison",designation: "Full Stack Developer",email: "mark@skote.com",projects: "121",skills: [
                    { name: "Ruby" },{ name: "Php" },{
                id: 5,img: avatar4,name: "Minnie Walter",email: "minnie@skote.com",projects: "145",{
                id: 6,img: avatar5,name: "Shirley Smith",email: "shirley@skote.com",projects: "136",{ name: "UI/UX Designer" }
                ]
            },{
                id: 7,name: "John Santiago",email: "john@skote.com",{
                id: 8,img: avatar7,name: "Colin Melton",email: "colin@skote.com",];

    const DefaultEvents = [{
        id: 1,title: 'Hey!',start: new Date().setDate(new Date().getDate() + 1),className: 'bg-warning text-white'
    },{
            id: 2,title: 'See John Deo',start: new Date(),end: new Date(),className: 'bg-success text-white'
        },{
            id: 3,title: 'Meet John Deo',start: new Date().setDate(new Date().getDate() + 8),className: 'bg-info text-white'
        },{
            id: 4,title: 'Buy a Theme',start: new Date().setDate(new Date().getDate() + 7),className: 'bg-primary text-white'
        }];

    const DefaultCategories = [
        {
            id: 1,title: 'New Theme Release',type: 'success'
        },title: 'My Event',type: 'info'
        },title: 'Meet Manager',type: 'warning'
        },title: 'Report Error',type: 'danger'
        },];
    const event1= { id: 0,title: "",title_category: "",start: "",className: "",category: "",event_category: "" };
    const [calendarEvents,setCalendarEvents] = useState(DefaultEvents);
    const [categories,setCategories] = useState(DefaultCategories);
    const [modal,setModal] = useState(false);
    const [modal1,setModal1] = useState(false);
    const [modalcategory,setModalcategory] = useState(false);
    const [event,setEvent] = useState(event1);
    const [selectedDay,setSelectedDay] = useState(0);
    const title_category = false;

    const calendarComponentRef = React.createRef();
    

    useEffect(() => {
        new Draggable(document.getElementById("external-events"),{
            itemSelector: '.external-event',});
    });

    /**
     * Handling the modal state
     */
    function toggle() {
        setModal(!modal)
    }

    function toggle1() {
        setModal1(!modal1)
    }

    function togglecategory() {
        setModalcategory(!modalcategory)
    }

    /**
     * Handling date click on calendar
     */
    const handleDateClick = (arg) => {
        setSelectedDay(arg);
        toggle();
    }

    /**
     * Handling click on event on calendar
     */
    const handleEventClick = (arg) => {
        const eventNew = arg.event;

        const event_tmp = { id: eventNew.id,title: eventNew.title,title_category: eventNew.title_category,start: eventNew.start,className: eventNew.classNames,category: eventNew.classNames[0],event_category: eventNew.classNames[0] };

        setEvent(event_tmp);
        toggle1();
    }

    /**
     * Handling submit event on event form
     */
    const handleValidEventSubmit = (e,values) => {
        var newEvent = {};


        newEvent = {
            id: calendarEvents.length + 1,title: values['title'],start: selectedDay ? selectedDay.date : new Date(),className: values.category + ' text-white'
        };


        // save new event
        setCalendarEvents(calendarEvents.concat(newEvent));
        setSelectedDay(null);

        toggle();
    }

    const handleValidEventSubmitEvent = (e,values) => {
        var newEvent = {};
        newEvent = { id: event.id,title: values.title,classNames: values.category + ' text-white',start: event.start };
        //first,remove array item,which we want to edit
        let filteredArray = calendarEvents.filter(item => item.id + "" !== event.id + "");

        //then concat update item details
        let NewArray = filteredArray.concat(newEvent);

        //store to state
        setCalendarEvents(NewArray);
        setEvent(null);
        setSelectedDay(null);

        toggle1();
    }

    const handleValidEventSubmitcategory = (e,values) => {

        var newEvent = {};

        newEvent = {
            id: calendarEvents.length + 1,title: values['title_category'],type: values.event_category
        };
        // categories.concat(newEvent);
        setCategories(categories.concat(newEvent));

        togglecategory();
    }

    /**
     * On calendar drop event
     */
    const onDrop = (event) => {
        const draggedEl = event.draggedEl;

        var newEvent = {
            id: calendarEvents.length + 1,title: draggedEl.innerText,start: event.date,className: draggedEl.getAttribute('data-type') + ' text-white'
        };

        // save new event
        setCalendarEvents(calendarEvents.concat(newEvent));
    }


    return (
             <React.Fragment>
                <div className="page-content">
                    <Container fluid>

                        {/* Render Breadcrumbs */}
                        <Breadcrumbs title="Contacts" breadcrumbItem="Users List" />
                        <Card>
                            <CardBody>
                                <Row>
                                    <Col lg={3}>
                                        <Button color="primary" className="font-16 btn-block" onClick={() => togglecategory() }>
                                            <i className="mdi mdi-plus-circle-outline"></i> Create New Event
                                        </Button>

                                        <div id="external-events" className="mt-3">
                                            <p className="text-muted">Drag and drop your event or click in the calendar</p>

                                            {categories.map((category,i) => {
                                                return <Alert color={category.type}>{category.title} </Alert>
                                            })}
                                        </div>
                                        </Col>
                                    <Col className="col-lg-3">
                                        <div className="table-responsive">
                                            <Table className="table-centered table-nowrap table-hover">
                                                <thead className="thead-light">
                                                <tr>
                                                    <th scope="col" style={{ width: "70px" }}>#</th>
                                                    <th scope="col">Name</th>
                                                </tr>
                                                </thead>
                                                <tbody>
                                                {
                                                    employees.map((user,i) =>
                                                        <tr key={"_user_" + i} >
                                                            <td>
                                                                {
                                                                    user.img === "Null"
                                                                        ? <div className="avatar-xs">
                                                                                <span className="avatar-title rounded-circle">
                                                                                    {user.name.charAt(0)}
                                                                                </span>
                                                                        </div>
                                                                        : <div>
                                                                            <img className="rounded-circle avatar-xs" src={user.img} alt="" />
                                                                        </div>
                                                                }

                                                            </td>
                                                            <td>
                                                                <h5 className="font-size-14 mb-1"><Link to="#" className="text-dark">{user.name}</Link></h5>
                                                                <p className="text-muted mb-0">{user.designation}</p>
                                                            </td>
                                                        </tr>
                                                    )
                                                }
                                                </tbody>
                                            </Table>
                                        </div>

                                    </Col>
                                    <Col className="col-lg-6">
                                        {/* fullcalendar control */}
                                        <FullCalendar ref={calendarComponentRef} defaultView="dayGridMonth" plugins={[BootstrapTheme,dayGridPlugin,interactionPlugin]}
                                                      slotDuration={'00:15:00'}
                                                      minTime={'08:00:00'}
                                                      maxTime={'19:00:00'}
                                                      handleWindowResize={true}
                                                      themeSystem="bootstrap"
                                                      header={{
                                                          left: 'prev,next today',center: 'title',right: 'dayGridMonth,dayGridWeek,dayGridDay'
                                                      }}
                                                      events={calendarEvents}
                                                      editable={true}
                                                      droppable={true}
                                                      eventLimit={true}
                                                      selectable={true}
                                                      dateClick={handleDateClick}
                                                      eventClick={handleEventClick}
                                                      drop={onDrop}
                                                      id="calendar" />

                                        <button onClick={() => togglecategory() }
                                                className="btn btn-secondary float-right btn-lg waves-effect btn btn-secondary">
                                            Neuen Termin anlegen
                                        </button>
                                        {/* New event modal */}
                                        <Modal isOpen={modal} toggle={() => toggle()} className="">
                                            <ModalHeader toggle={() => toggle()} tag="h4">
                                                Add Event
                                            </ModalHeader>
                                            <ModalBody>
                                                <AvForm onValidSubmit={handleValidEventSubmit}>
                                                    <Row form>
                                                        <Col className="col-12">
                                                            <AvField name="title" label="Event Name" type="text" errorMessage="Invalid name" validate={{
                                                                required: { value: true }
                                                            }} value={event ? event.title : ''} />
                                                        </Col>
                                                        <Col className="col-12">
                                                            <AvField type="select" name="category" label="Select Category"
                                                                     value={event ? event.category : 'bg-primary'}>
                                                                <option value="bg-danger">Danger</option>
                                                                <option value="bg-success">Success</option>
                                                                <option value="bg-primary">Primary</option>
                                                                <option value="bg-info">Info</option>
                                                                <option value="bg-dark">Dark</option>
                                                                <option value="bg-warning">Warning</option>
                                                            </AvField>
                                                        </Col>
                                                    </Row>
                                                    <Row>
                                                        <Col>
                                                            <div className="text-right">
                                                                <button type="button" className="btn btn-light mr-2" onClick={() => toggle()}>Close</button>
                                                                <button type="submit" className="btn btn-success save-event">Save</button>
                                                            </div>
                                                        </Col>
                                                    </Row>
                                                </AvForm>
                                            </ModalBody>
                                        </Modal>

                                        {/* edit event modal */}
                                        <Modal isOpen={modal1} toggle={() => toggle1()} className="">
                                            <ModalHeader toggle={() => toggle1()} tag="h4">
                                                Edit Event
                                            </ModalHeader>
                                            <ModalBody>
                                                <AvForm onValidSubmit={handleValidEventSubmitEvent}>
                                                    <Row form>
                                                        <Col className="col-12">
                                                            <AvField name="title" label="Event Name" type="text" errorMessage="Invalid name" validate={{
                                                                required: { value: true }
                                                            }} value={event ? event.title : ''} />
                                                        </Col>
                                                        <Col className="col-12">
                                                            <AvField type="select" name="category" label="Select Category"
                                                                     value={event ? event.category : 'bg-primary'}>
                                                                <option value="bg-danger">Danger</option>
                                                                <option value="bg-success">Success</option>
                                                                <option value="bg-primary">Primary</option>
                                                                <option value="bg-info">Info</option>
                                                                <option value="bg-dark">Dark</option>
                                                                <option value="bg-warning">Warning</option>
                                                            </AvField>
                                                        </Col>
                                                    </Row>
                                                    <Row>
                                                        <Col>
                                                            <div className="text-right">
                                                                <button type="button" className="btn btn-light mr-2" onClick={() => toggle()}>Close</button>
                                                                <button type="submit" className="btn btn-success save-event">Save</button>
                                                            </div>
                                                        </Col>
                                                    </Row>
                                                </AvForm>
                                            </ModalBody>
                                        </Modal>

                                        <Modal isOpen={modalcategory} toggle={() => togglecategory()} className="">
                                            <ModalHeader toggle={() => togglecategory()} tag="h4">
                                                Add a category
                                            </ModalHeader>
                                            <ModalBody>
                                                <AvForm onValidSubmit={handleValidEventSubmitcategory}>
                                                    <Row form>
                                                        <Col className="col-12">
                                                            <AvField name="title_category" label="Category Name" type="text" errorMessage="Invalid name" validate={{
                                                                required: { value: true }
                                                            }} value={title_category ? event.title_category : ''} />
                                                        </Col>
                                                        <Col className="col-12">
                                                            <AvField type="select" name="event_category" label="Choose Category Color"
                                                                     value={event ? event.event_category : 'bg-primary'}>
                                                                <option value="bg-danger">Danger</option>
                                                                <option value="bg-success">Success</option>
                                                                <option value="bg-primary">Primary</option>
                                                                <option value="bg-info">Info</option>
                                                                <option value="bg-dark">Dark</option>
                                                                <option value="bg-warning">Warning</option>
                                                            </AvField>
                                                        </Col>
                                                    </Row>
                                                    <Row>
                                                        <Col>
                                                            <div className="text-right">
                                                                <button type="button" className="btn btn-light mr-2" onClick={() => togglecategory()}>Close</button>
                                                                <button type="submit" className="btn btn-success save-event">Save</button>
                                                            </div>
                                                        </Col>
                                                    </Row>
                                                </AvForm>
                                            </ModalBody>
                                        </Modal>
                                    </Col>
                                </Row>
                            </CardBody>
                        </Card>
                    </Container>
                </div>
            </React.Fragment>
          );
    }
        
export default ContactsList;

任何提示或帮助将不胜感激-预先感谢您!

解决方法

几件事:

  • 您不应该在函数本身中获取数据-每次渲染组件时都会触发获取。通常,您希望在首次渲染组件时开始获取:
useEffect(() => {
  fetchData().then(response => {
    const employees = JSON.parse(response)
    setEmployees(employees)
  })
},[])

另请参阅以下问题:ReactJS: how to call useEffect hook only once to fetch API data

现在我们已经有了一种正确的数据获取方法,接下来我们要问另一个问题-what to set the state to by definition。换句话说,如何初始化数据。人们可能会告诉您它可以是任何东西,但是实际上,如果您使用的是数组(您正在对employee对象进行迭代,那么我假设它是一个数组),那么最好使用一个空数组初始化它。这样,类型就不会改变,下面的JSX不需要其他条件逻辑来处理不同类型的员工。

const [employees,setEmployees] = useState([])

我通常首先从useState调用开始,然后再调用useEffect。实际上,如果不确定将其交换,它是否会中断。因此,总代码为:


const fetchData = async () => {
    const res = await fetch('https://swapi.dev/api/people/')
    const json = await res.json()
    return json.result
}

const ContactsList = props => {
  const [employees,setEmployees] = useState([])

  useEffect(() => {
    fetchData().then(employees => {
      setEmployees(employees)
    })
  },[])

  return (
    <div>
      {employees.map(employee => <div key={employee.id}>{employee.name}</div>)}
    </div>
  )
}

更一般的说明:

  • 您的组件很大。 React的优点在于您可以将其划分为子组件。这不仅对您自己是一个好习惯,而且对于其他StackOverflow用户来说也更容易理解您的问题。只保留真正需要的组件。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res