Reputation: 166
I want to move the value of an object received by an API from one component to another.
I would like to use this "countryInfo.todayCases" inside SubCard component in App.js file as prop. For example where it says in App.js <SubCard title="Cases" cases={countryInfo.todayCases} total={2000} />
but I couldn't access this info from Header.js
. I have googled everywhere and couldn't find something similar to my case. Your help is much appreciated
App.js
import Header from "./components/Header";
import SubCard from "./components/SubCard";
function App() {
return (
<div className="app">
<div className="app__left">
<Header />
<div className="app__stats">
<SubCard title="Cases" cases={_cases} total={2000} />
<SubCard title="Recovered" cases={4000} total={2000} />
<SubCard title="Deaths" cases={4000} total={2000} />
</div>
<Map />
</div>
<div className="app__right_bar">
<SideBar />
{/* Graph */}
</div>
</div>
);
}
export default App;
Header.js
function Header({ _cases, _recovered, _deaths }) {
const [countries, setCountries] = useState([]);
const [country, setCountry] = useState("worldwide");
const [countryInfo, setCountryInfo] = useState({});
const _cases = countryInfo.todayCases;
const _recovered = countryInfo.todayRecovered;
const _deaths = countryInfo.todayDeaths;
useEffect(() => {
// async -> send a request, wait for it and do something
const getCountriesData = async () => {
await fetch(`${COUNTRIES_URL}`)
.then((response) => response.json())
.then((data) => {
const countries = data.map((country) => ({
name: country.country, //country name ex United Kingdom
value: country.countryInfo.iso2, // country code ex: UK
}));
setCountries(countries);
});
};
getCountriesData();
}, []);
const onCountryChange = async (event) => {
const countryCode = event.target.value;
setCountry(countryCode);
const url =
countryCode === "worldwide"
? WORLDWIDE_URL
: `${COUNTRIES_URL}/${countryCode}`;
await fetch(url)
.then((response) => response.json())
.then((data) => {
setCountry(countryCode);
setCountryInfo(data);
});
};
console.log("Country info here >>>", countryInfo);
return (
<div className="app__header">
<h1>Covid 19 tracker</h1>
<FormControl className="app__dropdown">
<Select variant="outlined" onChange={onCountryChange} value={country}>
<MenuItem value="worldwide">Worldwide</MenuItem>
{countries.map((country) => (
<MenuItem value={country.value}>{country.name}</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
export default Header;
SubCard.js
function SubCard({ title, cases, total }) {
return (
<div>
<Card className="sub_card">
<CardContent>
{/*Title */}
<Typography color="primary">{title}</Typography>
{/*Number of Cases */}
<h2 className="card_cases">{cases}</h2>
{/*Total */}
<Typography className="card_total" color="textSecondary">
{total} Total
</Typography>
</CardContent>
</Card>
</div>
);
}
export default SubCard;
Upvotes: 3
Views: 1017
Reputation: 576
It appears that App calls Header and Subcard
/-> Header
App ->
\-> SubCard
In order for props to pass through to each component there are three options:
If you move the shared data to the Parent (App), then you can share that data with both its children as props.
Change the components so that the data flows down through props from the Parent > Child > GrandChild. Then the order of the components would be
App -> Header -> SubCard
You could use React Context to create a global variable to share between the components.
With any of these three choices, you need to rebalance how the code is laid out between the components.
Upvotes: 3