How to do conditional rendering in flatlist

172 Views Asked by At

I have fetched from an API that records the country name and population. I have the country names in a search flatlist. My goal is to display a small circle next to the country name on the flatlist based on its population. If the population is above 100M, the circle will be red, if its above 10M and less than 50M, the circle will be orange, if it's less than 10M, the circle will be green. Is the conditional rendering the correct way to do this? Or can I do it in a different way?

My current code is below:

const [filteredData, setFilteredData] = useState<any>();
const [masterData, setMasterData] = useState([]);
const [filteredPopulationData, setFilteredPopulationData] = useState<any>();
const [masterPopulationData, setMasterPopulationData] = useState([]);

useEffect(() => {
    fetchData();
    return () => {};
  }, []);

const fetchData = () => {
    const apiURL =
      "https://raw.githubusercontent.com/samayo/country-json/master/src/country-by-population.json";
    fetch(apiURL)
      .then((response) => response.json())
      .then((responseJson) => {
        setFilteredStateData(responseJson);
        setMasterStateData(responseJson);
      })
      .catch((error) => {
        console.error(error);
      });
  };

const SearchFilter = (text) => {
    if (text) {
      const newData = filteredData.filter((item) => {
        const itemData = item.country;

        const textData = text.toUpperCase();
        return itemData.indexOf(textData) > -1;
      });

      setFilteredData(newData);
      setSearch(text);
    } else {
      setFilteredData(masterData);
      setSearch(text);
    }
    if (text) {
      const newPopulationData = filteredPopulationData.filter((item) => {
        const itemPopulationData = item.population;

        const textPopulationData = text.toUpperCase();
        return itemPopulationData.indexOf(textPopulationData) > -1;
      });

      setFilteredPopulationData(newPopulationData);
      setSearch(text);
    } else {
      setFilteredPopulationData(masterPopulationData);
      setSearch(text);
    }

const renderExtraItem = ({ item }) => {
    if ((item.population < 10000000)) {
      return (
        <View
          style={{
            width: 10,
            height: 10,
            borderRadius: 20,
            backgroundColor: "green",
          }}
        />
      );
    } if ((item.population >= 10000000 && item.population < 50000000 )) {
      return (
        <View
          style={{
            width: 10,
            height: 10,
            borderRadius: 20,
            backgroundColor: "orange",
          }}
        />
      );
    } if ((item.population >= 100000000)) {
      return (
        <View
          style={{
            width: 10,
            height: 10,
            borderRadius: 20,
            backgroundColor: "red",
          }}
        />
      );
    }
  };

const ItemView = ({ item }) => {
    return (
      <RectButton
        onPress={() => navigate("LocationDataScreen", { name: item.country })}
      >
        <Text style={[styles.itemStyle, { textTransform: "capitalize" }]}>
          {item.id}
          {item.country.toUpperCase()}
        </Text>
        {renderExtraItem(item)}
      </RectButton>
    );
  };
const ItemSeparatorView = () => {
    return (
      <View
        style={{
          height: 1.5,
          width: "90%",
          marginLeft: 35,
          backgroundColor: "#f3f2f8",
        }}
      />
    );
  };

return (
<FlatList
        data={filteredData}
        keyExtractor={(item, index) => index.toString()}
        ItemSeparatorComponent={ItemSeparatorView}
        renderItem={ItemView}
        style={styles.listcontainer}
      />
)
2

There are 2 best solutions below

2
Ahmed Gaber On BEST ANSWER

yes it's the correct way.
take care about population >= xx or population > xx

your code may be like this:

const YourItemComponent = ({population}) => {

   //function that return color based on population
   const getCircleColor = (population) => {
      if(population >= 100000000) return "red";   
      if(population >= 10000000 && population < 50000000) return "orange"; 
      return "green";
   };

   return(
     <View>
        ...
        <Circle style={{backgroundColor : getCircleColor(population)}}>
      
        </Circle>
       ...
    </View>
   );

}

3
Josh On

You can simply have a function that displays a custom Element based on the said condition

 const renderExtraItem = (item) => {
    if (item.population > 100000000) {
      //render some custom view
      return (
        <View />
      )
    }

    if (item.population > 10000000 && item.population < 50000000) {
      // render something else
      return (<View />)
    }

    // render a default 
    return (<View />)
  }

  const ItemView = ({ item }) => {
    return (
      <RectButton
        onPress={() => navigate("LocationDataScreen", { name: item.country })}
      >
        <Text style={[styles.itemStyle, { textTransform: "capitalize" }]}>
          {item.id}
          {item.country.toUpperCase()}
        </Text>
        {renderExtraItem(item)}
      </RectButton>
    );
  };