Skip to content
Advertisement

React component not rendering at all

Here’s the code:

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


const FilterLengthZero = ({ setEmptyDetailedCountry }) => {
  useEffect(() => setEmptyDetailedCountry(), [])
  return <div>Type to search</div>
}

const FilterLengthNine = ({ setEmptyDetailedCountry }) => {
  useEffect(() => setEmptyDetailedCountry(), [])
  return <div>Too many matches. Type more!</div>
}

const FilterLengthGreaterThanOne = ({ filteredCountries, buttonHandler }) => {
  return (
    <div>
      {
        filteredCountries.map(country => (
          <CountryButton key={country.name.common} country={country} onClick={() => buttonHandler(country)} />
        ))
      }
    </div>
  )
}

const FilterLengthEqualToOne = ({ filteredCountries, setActualDetailedCountry }) => {
  useEffect(() => setActualDetailedCountry(filteredCountries[0]), [])
}

const Display = ({ country }) => {

  return (
    <div>
      <h2>Country</h2>
      <div>Capital {country.capital}</div>
      <div>Area {country.area}</div>
      <h3>Languages</h3>
      <ul>
        {Object.values(country.languages).map(language => (
          <li key={language}>{language}</li>
        ))}
      </ul>
      <img src={country.flags.png} />
    </div>
  );
};

const CountryButton = ({ country, onClick }) => {
  return (
    <div>
      {country.name.common}
      <button onClick={() => onClick(country)}>show</button>
    </div>
  );
};

const CheckConditions = ({ setEmptyDetailedCountry, filteredCountries, filter, buttonHandler, setActualDetailedCountry }) => {
  if (filter === '') {
    return <FilterLengthZero setEmptyDetailedCountry={setEmptyDetailedCountry} />
  }
  else if (filteredCountries.length > 9) {
    return <FilterLengthNine setEmptyDetailedCountry={setEmptyDetailedCountry} />
  }
  else if (filteredCountries.length > 1) {
    return <FilterLengthGreaterThanOne filteredCountries={filteredCountries} buttonHandler={buttonHandler} />
  }
  else if (filteredCountries.length === 1) {
    return <FilterLengthEqualToOne filteredCountries={filteredCountries} setActualDetailedCountry={setActualDetailedCountry} />
  }
  else {
    return <></>
  }
}

const CheckDetailedDisplayConditions = ({ detailedCountry }) => {
  if (detailedCountry.length != 1) {
    console.log('no detailed country')
    return <></>
  }
  else {
    console.log('1 detailed country')
    return <Display country={detailedCountry} />
  }
}

const App = () => {
  const [countries, setCountries] = useState([]);
  const [filter, setFilter] = useState('');
  const [detailedCountry, setDetailedCountry] = useState('');

  useEffect(() => {
    axios.get('https://restcountries.com/v3.1/all').then(response => {
      setCountries(response.data);
    });
  }, []);

  const buttonHandler = country => {
    setDetailedCountry(country);
  };

  const filterHandler = event => {
    setFilter(event.target.value);
  };

  const filterCountries = country => {
    return country.name.common.toLowerCase().includes(filter.toLowerCase());
  };

  const countriesSubset = countries.filter(filterCountries);

  function setEmptyDetailedCountry() {
    setDetailedCountry('')
  }

  function setActualDetailedCountry(country) {
    setDetailedCountry(country)
  }

  return (
    <div>
      find country: <input onChange={filterHandler} />
      <CheckConditions
        setEmptyDetailedCountry={setEmptyDetailedCountry}
        filteredCountries={countriesSubset}
        filter={filter}
        buttonHandler={buttonHandler}
        setActualDetailedCountry={setActualDetailedCountry} />
      <CheckDetailedDisplayConditions detailedCountry={detailedCountry} />
    </div>
  );
};

export default App;

I’ve been trying to learn React using this online MOOC. I’m on exercise 2.12* Data for countries, step1 and I’m stuck. My search is running fine but I’m unable to solve the last part of the problem: printing information of a selected country or if only 1 country matches the search string.

I tried debugging through console.log and it turns out that whenever I’m calling the ‘setDetailedCountry’ method, it’s never working. My ‘DetailedCountry’ hook is always empty!

Please help me figure out what the problem is.

Advertisement

Answer

setDetailedCountry works as intended

Your detailedCountry doesn’t have property length so in CheckDetailedDisplayConditions detailedCountry.length != 1 always resolves as true

Maybe use detailedCountry instead

const CheckDetailedDisplayConditions = ({ detailedCountry }) => {
  if (!detailedCountry) {
    console.log('no detailed country')
    return <></>
  }
  else {
    console.log('1 detailed country')
    return <Display country={detailedCountry} />
  }
}
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement