I am working on countries project.
I get information about this when the border buttons are clicked. But when I click the Back button, the previous country data does not appear. How can I fix this? Please help me!
Here is my Country Component
import React, { useEffect, useState } from 'react';
import { Link, useParams, useNavigate } from 'react-router-dom';
import Loading from './Loading';
function Country() {
const { countryCode } = useParams();
const navigate = useNavigate();
const [country, setCountry] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => { getSingleCountryData(countryCode); }, []);
const getSingleCountryData = async (countryCode) => {
setLoading(true);
try {
const country = JSON.parse(localStorage.getItem("countries")).filter(c => c.cca3 === countryCode);
setCountry(country[0]);
setLoading(false);
} catch (err) {
console.log(err);
}
}
return loading ? <Loading />
: (
<div className='country container'>
<button className='btn backBtn' onClick={() => navigate(-1)}> Back </button>
// some code
<div className="country__borders">
<h4>Border Countries:</h4>
{country.borders && country.borders.map((border, index) => {
return <Link to={`/countries/${border}`} onClick={() => getSingleCountryData(border)} key={index} className='btn'>{border}</Link>
})}
</div>
</div>
);
}
export default Country;
The useEffect hook is missing the getSingleCountryData and countryCode as dependencies. You'll want to memoize the getSingleCountryData callback so it's provided to the useEffect hook as a stable callback reference.
const getSingleCountryData = useCallback(async (countryCode) => {
setLoading(true);
try {
const country = (JSON.parse(localStorage.getItem("countries")) || [])
.filter(c => c.cca3 === countryCode);
setCountry(country[0]);
} catch (err) {
console.log(err);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
getSingleCountryData(countryCode);
}, [countryCode, getSingleCountryData]);
Since the country data is fetched and loaded when the countryCode route param updates there'll no longer be a need to trigger this fetching when the link is clicked.
{country.borders && country.borders.map((border, index) => (
<Link
key={index}
to={`/countries/${border}`}
className='btn'
>
{border}
</Link>
))}
And since the data is not longer fetched via a click handler and only referenced in the useEffect, getSingleCountryData can be moved into the useEffect hook and be removed entirely as a dependency.
const getSingleCountryData = useCallback(, []);
useEffect(() => {
const getSingleCountryData = async (countryCode) => {
setLoading(true);
try {
const country = (JSON.parse(localStorage.getItem("countries")) || [])
.filter(c => c.cca3 === countryCode);
setCountry(country[0]);
} catch (err) {
console.log(err);
} finally {
setLoading(false);
}
}
getSingleCountryData(countryCode);
}, [countryCode]);