Home > other >  React component not rendering at all
React component not rendering at all

Time:08-07

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.

CodePudding user response:

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} />
  }
}

CodePudding user response:

You set an object to detailedCountry.

const CheckDetailedDisplayConditions = ({ detailedCountry }) => {
  console.log("===== detailedCountry", detailedCountry);
  if (detailedCountry.length != 1) {
  ...
}

You can see the value of detailedCountry by logging its value. detailedCountry is not an array so you should not read the length value because it is always undefined and it is never equal to 1. You should check whether or not it is undefined or defiend.

  • Related