Counting number of occurrences in an array in React Project

Viewed 1410

I have a list of some countries' array that I'm fetching from an API. I have these countries in an array already but each country appears multiple times. I wrote a function to get the number of Occurrences of each country with the number of times they appear in an array to a separate array but I'm just getting an error message that " Objects are not valid as a React child".

Here is the link to the code sandbox https://codesandbox.io/s/peaceful-mayer-t2ii2?file=/src/App.js

My Code

import React, { Component } from "react";
import ReactDOM from "react-dom";
import axios from "axios";

export default class App extends Component {
  constructor(props) {
    super(props)
  
    this.state = {
       data: [],
       countries: [],
       countryoccurence: []
    }
  }
  componentDidMount() {
    this.fetchCountryData()
  }
  fetchCountryData = async () => {
    const url = 'https://api.thecatapi.com/v1/breeds'
    try {
      const response = await axios.get(url)
      const data = await response.data
      this.setState({
        data,
      })

      const [countries, countryoccurence] = this.catbreeds();
      this.setState({
        countries, countryoccurence
      })
    } catch (error) {
      console.log(error)
    }
  }



catbreeds(){
  const countries = (this.state.data.map((bill) => bill.origin));
console.log(countries) 
var countryoccurence = countries.reduce(function(obj, b) {
  obj[b] = ++obj[b] || 1;
  return obj;
}, {});

//   return [country, count];
  return [countries, countryoccurence]
  
}

  render() {
    return (
      <div>
         <ul>
          {this.state.countries}
        </ul>
        {this.state.countries}   {/*  This returns the list of the countries */}
        {this.state.countryoccurence}  {/*  // This is the part I'm having problem with. Actually, I'm expecting the reult of this line to be something like ["Greece", 6 "England", 8...] */}
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById("root"))
2 Answers

Working App: Codesandbox

enter image description here

import React, { Component } from "react";
import ReactDOM from "react-dom";
import axios from "axios";

export default class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: [],
      countries: [],
      countryoccurence: []
    };
  }
  componentDidMount() {
    this.fetchCountryData();
  }
  fetchCountryData = async () => {
    const url = "https://api.thecatapi.com/v1/breeds";
    try {
      const response = await axios.get(url);
      const data = await response.data;
      // console.log(data)
      this.setState({
        data
      });

      const [countries, countryoccurence] = this.catbreeds();
      this.setState({
        countries,
        countryoccurence
      });
    } catch (error) {
      console.log(error);
    }
  };

  catbreeds = () => {
    const countries = this.state.data.map((bill) => bill.origin);
    // console.log(countries)
    var countryoccurence = {};
   /* here we iterate over the list of countries,
     first, we check if that countries already exists
     in countryoccurence object, if it exists, we will increment
     it's count, if not then we will give it an initial value of 1.
   */
    countries.forEach((country) => {
      console.log(country);
      if (countryoccurence[country]) {
        countryoccurence[country] += 1;
      } else {
        countryoccurence[country] = 1;
      }
    });
    console.log("this:", countryoccurence);
    //   return [country, count];
    return [countries, countryoccurence];
  };

  render() {
    return (
      <div>
        {/* <ul>
          {this.state.countries}
        </ul> */}
        <p>All Countries: {this.state.countries.sort()}</p>
        <p>Occurences:{JSON.stringify(this.state.countryoccurence)}</p>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

The problem that is causing your error is exactly what the message says: you are trying to render a React object (arrays in React are Arrays) as a child in JSX, which is not valid. this.state.countries and this.state.countryoccurrence are both objects. You need to iterate over the array and return an element for each Array element using map or something.

Related