Axios 在 React 组件中无法正常工作

Posted

技术标签:

【中文标题】Axios 在 React 组件中无法正常工作【英文标题】:Axios not working correctly in React component 【发布时间】:2021-08-31 13:20:14 【问题描述】:

我的 React 应用中有一个带有侧边栏组件的页面文件。

import React,  Component  from 'react';
import Navbar from './../components/layout/Navbar';
import  Table  from './../components/layout/Table';
import  Sidebar  from './../components/layout/Sidebar';

export class LandingPage extends Component 
    render() 
        return (
            <div>
                <Navbar />
                <h2 >Affiliation Information</h2>
                <div className="wrapper">
                    <Table />
                    <Sidebar />
                </div>
            </div>
        )
    


export default LandingPage

这个侧边栏组件由一个输入文本框和一个提交按钮组成。这里的想法是用户在文本框中输入一些内容(例如:“La”),触发设置const interest 状态的事件处理程序,然后单击提交。然后submit 按钮将兴趣状态值插入到一个 url 字符串中,以便使用 Axios 调用我的 API,假设返回名称为“La”的任何项目的查询结果。 (例如:["contact_name": "John Latham"])。

import React,  useState, useEffect  from 'react';
import config from '../../config/config';
import axios from "axios";

export const Sidebar = () => 
    const [interest, setInterest] = useState(null);
    const [response, setResponse] = useState([]);
    const [loadingData, setLoadingData] = useState(true);
    console.log("At top: " + config.apiURL + `/affiliations/full?name=$interest`);

    function HandleChange(event) 
        setInterest(event.target.value);
    ;

    async function callYourAPI(interest) 
        await axios
            .get(config.apiURL + `/affiliations/full?name=$interest`)
            .then((res) => 
                setResponse(res.data);
                setLoadingData(false);
            )
            .catch(function (error) 
                console.log(error);
            );
    ;

    useEffect(() => 
        if (loadingData) 
            callYourAPI();
         else 
            console.log(response);
        
    , [loadingData, response]); // Makes the useEffect dependent on response.

    return (
        <div className="sidebar" style=
            borderLeft: "1px solid gray"
        >
            <h2 style= textAlign: "center" > Filter</h2>
            <form>
                <label style=>Name</label> <br />
                <input
                    placeholder="Type name"
                    style= textAlign: "center", marginRight: "10px", height: "25px", width: "200px" 
                    value=interest
                    onChange=HandleChange></input>
                <button className="btn btn-primary" onClick=() => callYourAPI(interest)> Search</button>
            </form>
        </div >
    )

但是,发生的情况是,当我最初在输入框中输入一个值时,它会正确设置状态,但是当我单击按钮时,一切都变得混乱! interest 变量变为未定义(该框被清除)并且该过程似乎在完成之前循环通过 Sidebar() 函数大约 3 次(以及同步 callYourAPI() 函数),但从未在我的 @ 中返回 console.log(response); 987654331@ 功能。在这一点上,我很困惑;我在这里做错了什么?!

更新:我已在我的表单onSubmit 中使用e.preventDefault() 进行了建议的更改。但是,这似乎是在加载时调用的,并且它陷入了对 API 的某种无限调用循环中。

export const Sidebar = () => 
    const [interest, setInterest] = useState("");
    const [response, setResponse] = useState([]);
    const [loadingData, setLoadingData] = useState(true);

    function HandleChange(event) 
        setInterest(event.target.value);
    ;

    async function callYourAPI(interest) 
        await axios
            .get(config.apiURL + `/affiliations/full?name=$interest`)
            .then((res) => 
                setResponse(res.data);
                setLoadingData(false);
            )
            .catch(function (error) 
                console.log(error);
            );

    ;

    return (
        <div className="sidebar" style=
            borderLeft: "1px solid gray"
        >
            <h2 style= textAlign: "center" > Filter</h2>
            <form onSubmit=(e) =>  e.preventDefault(); callYourAPI(interest); >
                <label style=>Name</label> <br />
                <input
                    placeholder="Type name"
                    style= textAlign: "center", marginRight: "10px", height: "25px", width: "200px" 
                    value=interest
                    onChange=HandleChange></input>
                <button className="btn btn-primary"> Search</button>
            </form>
        </div >
    )

【问题讨论】:

这能回答你的问题吗? How to prevent buttons from submitting forms 或者专门针对 React:React - Preventing Form Submission 问题:上面的例子看起来很有希望。您将如何替换我的 Sidebar 函数中的构造函数(例如:this.formSubmit = this.formSubmit.bind(this);)? 函数组件不需要绑定上下文。更多信息the context (this) 如果你真的想使用表单,只需将 callYourAPI 用法移动到 &lt;form onSubmit=(e) =&gt; e.preventDefault(); callYourAPI(interest); &gt; 【参考方案1】:

尝试像这样添加event.preventDefault()

function HandleChange(event) 
        event.preventDefault()
        setInterest(event.target.value);
    ;

提交表单时的默认行为是重新加载页面,从而重置状态。 event.preventDefault() 阻止页面的默认行为。

【讨论】:

不,它仍在重新加载页面并擦除状态。还有其他地方我需要添加preventDefault(比如按钮点击事件?)?我可以以某种方式将callYourAPI 函数移动到useEffect 中,并且只让它依赖于响应吗? 哦,对不起……我的错。您需要在 callYourAPI 函数中添加event.preventDefault()。按钮箭头函数会是这样的:&lt;button className="btn btn-primary" onClick=(event) =&gt; callYourAPI(interest, event)&gt; Search&lt;/button&gt; 然后在函数中:async function callYourAPI(interest, event) event.preventDefault(); * * * 好的,我最终能够让它工作,但在表单标签中使用了onSubmit=(e) =&gt; e.preventDefault(); callSearchAPI(interest); (我将 axios 函数的名称更改为callSearchAPI)。感谢您的帮助!

以上是关于Axios 在 React 组件中无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

React - 当 Axios 在单独的组件中调用时,setState 不会重新渲染页面

为啥子组件在 React 中没有通过 Axios 获得父组件的 props

ag-grid React Header组件选择所有复选框选项无法在移动设备和平板电脑上正常工作

警告:无法在 React 本机中对未安装的组件执行 React 状态更新

受保护的路由无法与 React 和 Firebase 一起正常工作

Axios 发布表单数据在本机反应中无法正常工作