【问题标题】:Axios not working correctly in React componentAxios 在 React 组件中无法正常工作
【发布时间】: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;

标签: javascript reactjs axios state use-effect


【解决方案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)。感谢您的帮助!
猜你喜欢
  • 2019-10-21
  • 2019-09-25
  • 2020-10-31
  • 2018-03-31
  • 1970-01-01
  • 2022-07-14
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多