Search code examples
reactjsconditional-rendering

React Conditional Rendering using switch


I want to render a component based on props passed by the parent component, then in the children component i evaluate the props using switch statement. I was unable to get return element based on props.length. I have searching for the way using conditional rendering properly in react, but it seems something in my code goes wrong and i didnt realize it until now.

//Countries.tsx
import React from "react";
import ListCountries from "./ListCountries";
import Country from "./Country";

const Countries = ({ data }) => {
  let dataLength = data.length;
  let component = null;
  switch (dataLength) {
    case dataLength === 1:
      component = <Country data={data} />;
      break;
    case dataLength > 1:
      component = <ListCountries data={data} />;
      break;
    case dataLength > 10:
      component = <div>Too many matches, specify another filter</div>;
      break;
    default:
      component = <p>Else statement</p>;
      break;
  }

  return <>{component}</>;
};

export default Countries;

export default function App() {
  const [countries, setCountries] = useState([]);
  const [filteredCountries, setFilteredCountries] = useState([]);
  const [query, setQuery] = useState(undefined);

  useEffect(() => {
    axios.get("https://restcountries.eu/rest/v2/all").then(res => {
      setCountries(res.data);
    });
  }, [query]);

  const inputSearchHandler = e => {
    setQuery(e.target.value);
    const res = countries.filter(country =>
      country.name
        .toLocaleUpperCase()
        .includes(e.target.value.toLocaleUpperCase())
    );
    setFilteredCountries(res);
  };

  console.log("countries : ", countries);
  console.log("countries length: ", countries.length);
  console.log("filtered : ", filteredCountries);
  console.log("filtered length: ", filteredCountries.length);
  return (
    <div className="App">
      <SearchField inputSearchHandler={inputSearchHandler} />
      <Countries data={filteredCountries} />
    </div>
  );
}```

Solution

  • There are a few things wrong with your code but I was able to get it to work:

    1. the switch statement isn't built for "greater than" / "less than" statements. Usually, switch is used like this:

       switch(number) {
           case 1: dothis();
           case 2: dothat();
       }
      

      there is a workaround, you could do this:

       switch(true) {
           case number > 1: dothis();
           case number < 1: dothat();
       }
      

      but i would stick to if, else if and else statements.

    2. You made a small error in this line:

       case dataLength > 1:
             // do something
       case dataLength > 10:
             // do something else
      

      If we assume dataLength is 11, it would still execute first case since the condition dataLength > 1 is true. To fix this, make sure to change the first statement to case dataLength > 1 && dataLength < 10

    3. I did some minor changes to make the code more readable.

    This is the final result:

    import React from "react";
    import ListCountries from "./ListCountries";
    import Country from "./Country";
    
    const Countries = ({ data }) => {
      const getComponent = () => {
        let dataLength = data.length;    
          if (dataLength === 1) return <Country data={data} />;
          else if (dataLength > 1 && dataLength < 10) return <ListCountries data={data} />;
          else if (dataLength > 10) return <div>Too many matches, specify another filter</div>;
          else return <p>Else statement</p>;    
      };
    
      return getComponent();
    };
    
    export default Countries;