Greg
Greg

Reputation: 256

React.js: How to pass props to components?

I want to make API call reusable and use it's functionality in other components. I am fetching API in Hook/index.js component. Then I want to iterate through data got from API in another component, make it as a parameter and use it in other components.
I've a Flag/index.js component for flag(img) and want to get url of the image as a parameter and use in Flag/index.js component.
Any help will be appreciated.
In Hook/index.js I fetch API


import React, { useState, useEffect } from "react";

import "./hook.scss";

export default function Hook(){
  const [data, setData] = useState([]);
  const [error, setError] = useState(null);
  const [search, setSearch] = useState("");
 
  const fetchData = () => {
    fetch("https://restcountries.eu/rest/v2/all")
      .then((res) => res.json())
      .then((result) => setData(result))
      .catch((err) => console.log("error"));
  };

  useEffect(() => {
    const searchResult = data && data.filter((item) => item.name.toLowerCase().includes(search));
    setSearch(searchResult);
  }, []);

  useEffect(() => {
    fetchData();
  }, []);


  return [data, error];
}

In App.js I'm mapping through API data

import React, { useState }from "react";
import Header from "./components/Header";
import SearchBar from "./components/SearchBar";
import Flag from "./components/Flag";
import useCountries from "./Hooks";

import "./App.scss";

export default function App () => {
  const [data, error] = useCountries();

  
  return (
    <div className="App">
      <SearchBar />
      <Header />
      {data &&
        data.map((country) => (
          <div className="CountryList" key={country.name}>
            <div className="CountryListImg">
              <img src={country.flag} alt="" width="80px" /> if change here to flag={country.flag} I see link in browser
            </div>
            <div className="countryName">{country.name}</div>
            <div className="population">{country.population}</div>
            <div className="region">{country.region}</div>
            <div>
              {country.languages.map((language, languageIndex) => (
                <div key={languageIndex}>{language.name}</div>
              ))}
            </div>
          </div>
        ))}
      <useCountries />
    </div>
  );
  return [data, error]
}

And my Flag/index.js component, of course doesn't work

import React from "react";

import "./flag.scss";

export default function Flag({flag}) {
  return (
    <div className="">
      <img src={flag} alt="" width="80px" />  
    </div>
  );
};

How to make work search bar. For now it says undefined in console

import React, {useState} from "react";


import "./SearchBar.scss";

export default function Searchbar({data}) {
    const [search, setSearch] = useState("");

   function handleChange(e) {
    setSearch(e.target.value);
  } 
console.log(data)
  return (
    <div className="SearchBar">
      <input
        className="input"
        type="text"
        placeholder="search country ..."
        value={data}
        onChange={handleChange}
      />

      {data && data.filter((item) => item.name.toLowerCase().includes(search))}
    </div>
  );
};

Upvotes: 0

Views: 109

Answers (3)

Ace Rimmer
Ace Rimmer

Reputation: 141

I am not completely sure if this answers the question, but to add the abstracted Flag class in you simply need to change this:

<img src={country.flag} alt="" width="80px" />

To this:

<Flag flag={country.flag} />

Upvotes: 1

Phuc Tran
Phuc Tran

Reputation: 23

Just use <Flag flag={country.flag} />

See online: https://stackblitz.com/edit/stackoverflow-63831710?file=src/App.js

Upvotes: 0

Nhut Dinh Ba
Nhut Dinh Ba

Reputation: 354

You need to use Flag component inside App component

    import React, { useState }from "react";
    import Header from "./components/Header";
    import SearchBar from "./components/SearchBar";
    import Flag from "./components/Flag";
    import useCountries from "./Hooks";
    
    import "./App.scss";
    
    export default () => {
      const [data, error] = useCountries();
    
      
      return (
        <div className="App">
          <SearchBar />
          <Header />
          {data &&
            data.map((country) => (
              <div className="CountryList" key={country.name}>
                <div className="CountryListImg">
                   <Flag flag={country.flag}/>
                </div>
                <div className="countryName">{country.name}</div>
                <div className="population">{country.population}</div>
                <div className="region">{country.region}</div>
                <div>
                  {country.languages.map((language, languageIndex) => (
                    <div key={languageIndex}>{language.name}</div>
                  ))}
                </div>
              </div>
            ))}
          <useCountries />
        </div>
      );
      return [data, error]
    }         

Upvotes: 1

Related Questions