onapte
onapte

Reputation: 267

How do I render the response data from axios in Reactjs

I am using axios to get data from a url. I am then storing the fetched data in post using setPost(). Once the data is stored in post, I am then decoding the data using a function getData() which further assigns the decoded data to metar using setMetar(). The user enters data in an input and clicks on the submit button to get the decoded data. The problem is that it takes 2 clicks to get the decoded data instead of 1. Here's my code:

import React, { useState, useEffect, useReducer, useCallback } from "react";
import "./Search.css";
import axios from "axios";
import parseMETAR from "metar";

let dataList = "";

const Search = () => {
  const [post, setPost] = useState(null);
  
  const [icao, setIcao] = useState("");
  const [metar, setMetar] = useState("");
  

  useEffect(() => {
    getData(icao);
  }, []);

  const getData = (code) => {
    try {
      console.log(code);
      const url = `Some url`;
      console.log(url);
      axios.get(url).then((response) => {
        setPost(response.data);  
        getMetar();
      });
      
    } catch (err) {
      console.log(err);
    }
  };


  const getMetar = () => {
    // decode the raw text
    setMetar(mtr);
  };

  const handleInputChange = (e) => {
    setIcao(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    getData(icao);
  };

  return (
    <div className="search-div">
      <h2>Search METAR</h2>
      <form>
        <input
          type="text"
          placeholder="Enter ICAO"
          onChange={(e) => handleInputChange(e)}
        />
        <button onClick={(e) => handleSubmit(e)}>Get Metar</button>
      </form>

      <h3>METAR: {metar.length > 0 && metar}</h3>
    </div>
  );
};

export default Search;

As soon as the button is clicked, the console shows the correct data stored in the icao. But, metar's value is not rendered. How do I wait for axios to get the fetched data? If this is not a problem, how do I force the Search component to re render after the update functions of each useState variables?

Upvotes: 0

Views: 627

Answers (2)

Hana Jiffry
Hana Jiffry

Reputation: 61

If you need to load data while the application is running, using the useEffect Hook is pretty simple.

import {useEffect} from 'react';

useEffect(() => {
  getMetar();
},[post])

Upvotes: 0

Rakib Uddin
Rakib Uddin

Reputation: 876

setPost is an asynchronous operation. And you are calling getMetar() right after it. As a result your first click is registering the payload and you are getting the data on second click. This way you are actually missing the data from 2nd api call. You will get the updated payload on your third click.

You can set a useEffect hook with post dependency. So when post get updated with the api data then you call getMetar()

  useEffect(() => {
    getMetar();
  }, [post]);

Upvotes: 2

Related Questions