简体   繁体   中英

How to send value from one component, to another

I have this prop in one of my components, which I'd like to pass to one other component and use as a variable there:

const VerContinentToolbar = (props) => {


   return (
     <Menu className="nav-icon">
       <CountryList displayFields={["countryName"]} />
     </Menu>
   );
 };

If I console.log(props.props), I get this: https://imgur.com/a/HnRHDcH This is the value that I want to pass to useCountries. The receiving component looks like this:

const useCountries = (props) => {
    const [countries, setCountries] = useState([])


    useEffect(() => {
        firebase
            .firestore()
            .collection("Africa")
            .onSnapshot((snapshot) => {
                const newCountries = snapshot.docs.map((doc) => ({
                    id: doc.id,
                    ...doc.data()
                }))
                setCountries(newCountries)
            })
    }, [])
    return countries
}



const CountryList = ({ displayFields = [] }) => {
    const countries = useCountries();
    console.log(countries)

    return (
        <div className="countries">
            {countries.map(country => (
                <div key={country.id}>

                    <div className="entry">

                        {displayFields.includes("continent") && (
                            <div>Name of continent: {country.continent}</div>

                        )}
                        {displayFields.includes("revName") && (
                            <div>{country.revName}</div>
                        )}
                        {displayFields.includes("countryName") && (
                            <div><Link to={"./Jumbotron"}>{country.countryName}</Link></div>
                        )}
                        {displayFields.includes("dest1") && (
                            <div>Destination 1: {country.dest1}</div>
                        )}
                        {displayFields.includes("dest2") && (
                            <div>Destination 2: {country.dest2}</div>
                        )}
                        {displayFields.includes("dest3") && (
                            <div>Destination 3: {country.dest3}</div>
                        )}
                        {displayFields.includes("beerPrice") && (
                            <div>Beer price: {country.beerPrice}</div>
                        )}
                        {displayFields.includes("foodPrice") && (
                            <div>Food price: {country.foodPrice}</div>
                        )}
                        {displayFields.includes("hostelPrice") && (
                            <div>Hostel price: {country.hostelPrice}</div>
                        )}
                        {displayFields.includes("review") && <div>Review: {country.review}</div>}
                        {displayFields.includes("imgUrl") && <img src={country.url} alt="no-img" />}
                    </div>
                </div>
            ))}
        </div>
    );
};

I have tried and tried to understand context, but I cannot really wrap my head around it. I'd like to put the value from props into ".collection("Africa")", but I have no clue how to. I've read the documentation for it, but I'm too thick headed to understand work it out properly.

If there's other solutions, I'm all ears.

What the props that I'd like to pass on is: I've created one component for each continent. In each component, I call the VerContinentToolbar, passing the prop/name of the continent, like this:

const Africa = ({}) => {

  return (
    <div>
      <VerContinentToolbar props={["Africa"]} />
This means, that

 const VerContinentToolbar = (props) => {

   return (
     <Menu className="nav-icon">
       <CountryList displayFields={["countryName"]} />
     </Menu>
   );
 };

Holds the word "Africa".

I'd like to pass on "Africa", to my component, which fetches the collection of the continent (in this case: Africa).

I want to pass the information that the prop helds to this:

const useCountries = (props) => {
    const [countries, setCountries] = useState([])


    useEffect(() => {
        firebase
            .firestore()
            .collection("Africa") <---- I WANT PROP FROM VERCONT HERE
            .onSnapshot((snapshot) => {
                const newCountries = snapshot.docs.map((doc) => ({
                    id: doc.id,
                    ...doc.data()
                }))
                setCountries(newCountries)
            })
    }, [])
    return countries
}

To clarify this even more, I've attached two pictures. Asia: Here, I want to render the collection "Asia", to display each review that belongs to a country within the continent of Asia.

https://imgur.com/a/bZhQAwz

So far, I've created "Imagination land" and attached it to "Africa" in Firebase. I want to show this, only in the Africa component. And obviously, I want to show all the countries with the Asia tag in the Asia component.

Thanks

EDIT: Problem is solved.

import React, { Component, useState, useEffect } from 'react'
import { Link } from 'react-router-dom';
import firebase from '../config'
import './Countries.css'
import props from './Navbar/VerContinentToolbar';



const useCountries = continent => {
    const [countries, setCountries] = useState([]);
      console.log('continent', continent) // <--- Get it as your first argument
      console.log(continent.toString())

    useEffect(() => {
        firebase
            .firestore()
            .collection(continent.toString())
            .onSnapshot((snapshot) => {
                const newCountries = snapshot.docs.map((doc) => ({

                    id: doc.id,

                    ...doc.data()

                }))
                setCountries(newCountries)

            })
    }, [])

    return countries
}



const CountryList = ({ continent, displayFields = []  }) => {
    const countries = useCountries(continent); // <--- Pass it in here

    return (
        <div className="countries">
            {countries.map(country => (
                <div key={country.id}>

                    <div className="entry">

                        {displayFields.includes("continent") && (
                            <div>Name of continent: {country.continent}</div>

                        )}
                        {displayFields.includes("revName") && (
                            <div>{country.revName}</div>
                        )}
                        {displayFields.includes("countryName") && (
                            <div><Link to={"./Jumbotron"}>{country.countryName}</Link></div>
                        )}
                        {displayFields.includes("dest1") && (
                            <div>Destination 1: {country.dest1}</div>
                        )}
                        {displayFields.includes("dest2") && (
                            <div>Destination 2: {country.dest2}</div>
                        )}
                        {displayFields.includes("dest3") && (
                            <div>Destination 3: {country.dest3}</div>
                        )}
                        {displayFields.includes("beerPrice") && (
                            <div>Beer price: {country.beerPrice}</div>
                        )}
                        {displayFields.includes("foodPrice") && (
                            <div>Food price: {country.foodPrice}</div>
                        )}
                        {displayFields.includes("hostelPrice") && (
                            <div>Hostel price: {country.hostelPrice}</div>
                        )}
                        {displayFields.includes("review") && <div>Review: {country.review}</div>}
                        {displayFields.includes("imgUrl") && <img src={country.url} alt="no-img" />}



}
                    </div>
                </div>

            ))}
        </div>
    );
};


export default CountryList
const VerContinentToolbar = (props) => {

  return (
    <Menu className="nav-icon">
      <CountryList
        continent={props.continent}
        displayFields={["countryName"]}
      />
    </Menu>
  );
};

Thanks for all your help.

  1. Pass it as a prop (continent) from your continent component

    const Africa = () => { return ( <div> <VerContinentToolbar continent="Africa" /> </div> ); };
  2. In <VerContinentToolbar /> , get the prop and pass it down to <CountryList /> . Rather than passing props down to grandchildren components you can use the context API for that or Redux for that.

     const VerContinentToolbar = props => { console.log('continent prop is now here', props.continent) return ( <Menu className="nav-icon"> <CountryList continent={props.continent} displayFields={["countryName"]} /> </Menu> ); };
  3. In <CountryList /> , get the prop ( continent ) and pass it into your useCountries hook.

     const CountryList = props => { const countries = useCountries(props.continent); // <--- Pass it in here console.log(countries) return ( <div className="countries"> {countries.map(country => ( {/*...code */} ))} </div> ); };
  4. And finally in your hook get it as the first argument

    const useCountries = continent => { const [countries, setCountries] = useState([]); console.log('continent', continent) // <--- Get it as your first argument //...code return countries }

As I understand your question to be, you want to within CountryList , call the useCountries hook to specify the collection you want.

const useCountries = (collection) => {
  const [countries, setCountries] = useState([])

  useEffect(() => {
    firebase
      .firestore()
      .collection(collection) // <-- pass collection argument here
      .onSnapshot((snapshot) => {
        const newCountries = snapshot.docs.map((doc) => ({
          id: doc.id,
          ...doc.data()
        }))
        setCountries(newCountries)
      })
  }, [])
  return countries
}

In CountryList pass the value you want to useCountries

const countries = useCountries('Africa');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM