gwydion93
gwydion93

Reputation: 1923

Axios not working correctly in React component

I have a page file in my React app that has a sidebar component.

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

This sidebar component consists of an input textbox and a submit button. The idea here is that the user types something into the textbox (Ex: "La") triggering an event handler that sets the state of const interest then clicks submit. The submit button then plugs the interest state value into a url string for a call to my API using Axios, which is suppose to return the query results of any items where name is like "La". (Ex: [{"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 >
    )
}

However, what happens is that when I initially type in a value in the input box, its sets the state correctly, but when I click the button, everything goes haywire! The interest variable becomes undefined (the box gets cleared) and the process seems to loop through the Sidebar() function about 3 times ( and the sync callYourAPI() function) before it finishes but never returns the console.log(response); in my useEffect() function. At this point I am confused; what am I doing wrong here?!

UPDATE: I have made the recommended changes, using e.preventDefault() in my forms onSubmit. However, it seems like this is called on load, and its stuck in some kind of infinite call loop to the 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 >
    )
}

Upvotes: 0

Views: 155

Answers (1)

Try adding event.preventDefault() like this:

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

The default behavior when submitting a form is to reload the page, therefore resetting the state. event.preventDefault() prevents the default behavior of the page.

Upvotes: 1

Related Questions