React-роутер не рендерит динамический c компонент - при нажатии ничего не происходит - PullRequest
1 голос
/ 16 апреля 2020

Я занимаюсь небольшим проектом и у меня есть список компонентов, которые отображают информацию о странах. Теперь я добавил реагирующий маршрутизатор, чтобы при нажатии на карту отображалась дополнительная информация об этой стране. Теперь, когда я нажимаю на карту, ничего не происходит! Ниже приведен код для стран.

import React, { Component } from 'react';
import { CountryList } from './Components/Card-List/CountryList';
import { SearchBox } from './Components/Search-box/Search-Box';
import './Countries.styles.css';
import  { DetailCountryCard }  from './Components/DetailCountryCard/DetailCountryCard';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';


class Countries extends Component {
constructor() {
    super();
    this.state = {
        countries:[],
        searchField:"",
        regionField:"",
        darkMode: false
    }
    this.setDarkMode = this.setDarkMode.bind(this);
};

componentDidMount() {
    fetch("https://restcountries.eu/rest/v2/all")
    .then(response => response.json())
    .then(all =>  this.setState({ countries: all,
        regions: all}))
    .catch(error => console.log("I have errored" + error));
}
setDarkMode(e){
    this.setState((prevState) => ({ darkMode: !prevState.darkMode }));
}
render() {
    const { countries, searchField, regionField, darkMode } = this.state;
    const filterCountries = countries.filter((country) => country.name.toLowerCase().includes(searchField.toLowerCase()) &&
     country.region.toLowerCase().includes(regionField.toLowerCase()));

     return(
        <Router>
            <div className={darkMode ? "dark-mode" : "light-mode" }>
                <nav className="navbar-items">
                    <h1 className="header">Where in the World</h1>
                    <div className="moon-end">
                    <button onClick={this.setDarkMode}>
                    <i className={darkMode ? "moon fas fa-moon" : "moon far fa-moon" }></i> 
                    </button>
                    <h2>{darkMode ? "Dark Mode" : "Light Mode" }</h2>



                    </div>
                </nav>


                <div className="Input">

                    < SearchBox type="search" placeholder="Search a Country" handlechange={e=> this.setState({
                        searchField: e.target.value })}
                        />

                        < SearchBox type="regions" placeholder="Filter by Regions" handlechange={e=> this.setState({
                            regionField: e.target.value })}
                            />

                </div>
                <CountryList countries={filterCountries} />

                    {/* <Route path="/" exact component={Countries} /> */}
                   <Switch>
                    <Route path="/card-detail/:name" component={ DetailCountryCard } exact/>
                    </Switch>

            </div>
            </Router>
    );
   }
 }

export default Countries

Ссылка для каждой карты находится в следующем компоненте:

import React from 'react';
import './CountryList.styles.css';
import {Link} from 'react-router-dom'
import { CountryCard } from '../Card/CountryCard';

export const CountryList = (props) => (
<div className='card-list'>
{props.countries.map(country => (
   <Link to={`/card-detail/${country.name}`} >
   <CountryCard key={country.alpha2Code} country={country} />
   </Link>
 ))}

</div>
);

Это должно go на следующий компонент:

import React from 'react';
import { useEffect } from 'react';
import { useState } from 'react';


export const DetailCountryCard = ({match}) => {
useEffect(() => {
    fetchItem();
    console.log(match);
},[])

const [country, setCountry] = useState([])

const fetchItem = async ()=> {
  const fetchCountry = await    fetch(`https://restcountries.eu/rest/v2/name/${match.params.name}`);
  const countries = await fetchCountry.json();
  setCountry(countries);
  console.log(country);

 }

  return (
    <div>
        {country.map(town => (

   <div>

    <h1 key={town.alpha2Code}>{town.name}</h1>
    <p>Native Name{town.nativeName}</p>
    <p>Region: {town.region}</p>
    <p>Languages: {town.languages[0].name}</p>
  </div>

  ))}
    </div>
);
}

Не уверен, что мне не хватает. Я не думаю, что я сделал опечатку на компоненте. Так не уверен, почему это не рендеринг? Любая помощь будет оценена.

1 Ответ

0 голосов
/ 18 апреля 2020

Вам просто нужно добавить зависимость match в useEffect в DetailCountryCard. Потому что [] это s similar in Class Component componentDidMount () `и вам нужно слушать, когда совпадение меняется.

Это окончательный код DetailCountryCard:

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

export const DetailCountryCard = ({ match }) => {
  useEffect(() => {
    fetchItem();
    console.log(match);
  }, [match]);

  const [country, setCountry] = useState([]);

  const fetchItem = async () => {
    const fetchCountry = await fetch(
      `https://restcountries.eu/rest/v2/name/${match.params.name}`
    );
    const countries = await fetchCountry.json();
    setCountry(countries);
    console.log(country);
  };

  return (
    <div>
      {country.map(town => (
        <div>
          <h1 key={town.alpha2Code}>{town.name}</h1>
          <p>Native Name{town.nativeName}</p>
          <p>Region: {town.region}</p>
          <p>Languages: {town.languages[0].name}</p>
        </div>
      ))}
    </div>
  );
};

Я тестировал в CodeSandBox и это работает! Link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...