timmyx
timmyx

Reputation: 166

How to pass objects and states between two components in React

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

Answers (1)

jaesle
jaesle

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:

Move the shared data to the Parent

If you move the shared data to the Parent (App), then you can share that data with both its children as props.

Parent > Child > GrandChild

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

React Context

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

Related Questions