Как отправить значение из одного компонента в другой - PullRequest
2 голосов
/ 17 апреля 2020

У меня есть эта опора в одном из моих компонентов, которую я хотел бы передать другому компоненту и использовать там в качестве переменной:

const VerContinentToolbar = (props) => {


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

Если я console.log (props.props) , Я получаю это: https://imgur.com/a/HnRHDcH Это значение, которое я хочу передать useCountries. Получающий компонент выглядит следующим образом:

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>
    );
};

Я пытался понять контекст, но не могу действительно обернуть его вокруг. Я хотел бы поместить значение из реквизита в ".collection (" Африка ")", но я понятия не имею, как это сделать. Я прочитал документацию для него, но я слишком тупой, чтобы понять, как это правильно работать.

Если есть другие решения, я весь слух.

Что за подпорки Я хотел бы передать следующее: я создал один компонент для каждого континента. В каждом компоненте я вызываю VerContinentToolbar, передавая реквизит / название континента, например:

const Africa = ({}) => {

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

 const VerContinentToolbar = (props) => {

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

Содержит слово «Африка».

Я хотел бы передать «Африка», в мой компонент, который собирает коллекцию континента (в данном случае: Африка).

Я хочу передать информацию, которую содержит реквизит, этому:

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
}

Чтобы уточнить это еще больше, я приложил две фотографии. Азия: здесь я хочу сделать коллекцию «Азия», чтобы отобразить каждый отзыв, принадлежащий стране на азиатском континенте.

https://imgur.com/a/bZhQAwz

До сих пор я создал «Землю воображения» и прикрепил ее к «Африке» в Firebase. Я хочу показать это, только в африканском компоненте. И, конечно же, я хочу показать все страны с тегом Asia в компоненте Asia.

Спасибо

EDIT: проблема решена.

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>
  );
};

Спасибо за вашу помощь.

Ответы [ 2 ]

2 голосов
/ 17 апреля 2020
  1. Передайте это как опору (континент) от вашего компонента континента

    const Africa = () => {
      return (
        <div>
          <VerContinentToolbar continent="Africa" />
        </div>
      );
    };
    
  2. В <VerContinentToolbar />, получите опору и передайте ее до <CountryList />. Вместо передачи реквизитов компонентам внуков вы можете использовать контекстный API для этого или Redux для этого.

    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. В <CountryList /> получите реквизит (continent) и передайте его в свой useCountries хук.

    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. И, наконец, в своем хуке получите его в качестве первого аргумента

    const useCountries = continent => {
      const [countries, setCountries] = useState([]);
      console.log('continent', continent) // <--- Get it as your first argument
    
      // ...code
      return countries
    }
    
1 голос
/ 17 апреля 2020

Как я понимаю, ваш вопрос в том, что вы хотите в CountryList вызвать хук useCountries, чтобы указать нужную коллекцию.

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
}

В CountryList передать нужное значение до useCountries

const countries = useCountries('Africa');
...