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?
CodePudding user response:
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]);
CodePudding user response:
If you need to load data while the application is running, using useEffect Hook is pretty simple.
import {useEffect} from 'react';
useEffect(()=>{
getMetar();
},[post])