I made a search bar that allows the user to search all sports available in one specific city (if sport is not defined) or a specific sport in a specific city (if sport is defined).
City will allways be defined.
I put 2 inputs (city and sport) on my searchbar and I want immediate results (so that there is a request to my API without any button "search" that triggers the request).
So when the user types something on the city input it triggers a request to the API and when he types something on the sport input it retriggers the request but this time with the city and the sport defined.
Both inputs values are store in states (city and sport).
I manage to do something that seems to work, the only problem is that if I types a sport in my input search, it does not update my request to the API. I have to retype the sport in my input a second time so that the request is updated.
I don't know why it does not update the first time I types something in my sport input because I have specified on my useEffect array that it must re render when the sport state changes.
Can someone help me understand this ?
My code :
import React, { useState, useEffect } from "react";
import style from "../styles/pdrs.module.css";
import axios from "axios";
import SearchBar from "../components/SearchBar";
const Pdrs = ({ setSearchCity, searchSport, setSearchSport }) => {
// if request's result is loading
const [isLoading, setIsLoading] = useState(false);
// search result
const [searchresults, setSearchresults] = useState(
"Lancez une recherche avec au moins une ville !"
);
// state for the searchbar request
const [city, setCity] = useState("");
const [sport, setSport] = useState(0);
// get city's id for API's request
const fetchCity = async () => {
setIsLoading(true);
try {
// city search
const cityResponse = await axios.get(
`${baseAPI}/city/name=${searchCity}`
);
const city = cityResponse.data;
setCity(city);
setIsLoading(false);
} catch (error) {
console.log(error.message);
setIsLoading(false);
}
};
//fetching sport id
const fetchSport = async () => {
setIsLoading(true);
try {
const sportResponse = await axios.get(
`${baseAPI}/activity/name=${searchSport}`
);
setSport(sportResponse.data.data[0].macro_activity_id);
setIsLoading(false);
} catch (error) {
console.log(error.message);
}
};
//fetching final request response
const fetchDataRequest = async () => {
try {
setIsLoading(true);
const results = await axios.get(
`${baseAPI}/pdrs?city_id=${city.id}${
sport ? "¯o_activity_id=" + sport : ""
}`
);
// manage search results
if (results.data.nb_results === 1) {
setSearchresults({
data: [results.data.data],
nb_results: 1,
});
setNbResults(1);
setIsLoading(false);
} else {
setSearchresults(results.data);
setNbResults(results.data.nb_results);
setIsLoading(false);
}
} catch (error) {
console.log(error.message);
setSearchresults(
"Sorry, nothing was found... !"
);
}
};
useEffect(() => {
if (searchCity) {
fetchCity();
}
if (searchSport) {
fetchSport();
}
}, [searchCity, searchSport]);
useEffect(() => {
if (searchCity) {
fetchDataRequest();
}
}, [searchCity, searchSport]);
console.log(searchresults);
return <>
<main className={`container ${style.pdrs}`}>
<section className={style.searchbar}>
<SearchBar
searchCity={searchCity}
setSearchCity={setSearchCity}
searchSport={searchSport}
setSearchSport={setSearchSport}
searchInstallation={searchInstallation}
setSearchInstallation={setSearchInstallation}
searchType={searchType}
setSearchType={setSearchType}
setPage={setPage}
/>
</section>
<section className={style.results}>
{isLoading ? (
<div>Loading...</div>
) : typeof searchresults === "string" ? (
<div className={`${style.container} ${style.noResults}`}>
<h2>{searchresults}</h2>
</div>
) : (
<>
<div className={style.container}>
<div className={style.resultsList}>
{searchresults.data.map((pdrs) => {
return (
// some code displaying the result
);
})}
</div>
</div>
</>
)}
</section>
</main>
</>;
};
export default Pdrs;
question from:
https://stackoverflow.com/questions/65846257/why-is-my-state-only-updated-on-the-second-state-change-instead-of-first-state-c 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…