Mapping JSON object to HTML This is a continuation of previous questions. I just started using react and I've managed to fetch a xml file, convert it to json and then loop through the data. But I think there should be a better way to go through what I've done as I'm using a function I found on another SO answer and then used a map() within it. 

Anyways here's the breakdown of my code.

Fetching the xml and converting to json:

componentDidMount() {
    axios.get('https://gist.githubusercontent.com/eMatsiyana/e315b60a2930bb79e869b37a6ddf8ef1/raw/10c057b39a4dccbe39d3151be78c686dcd1101aa/guestlist.xml')
    .then(res =&gt; {
      const xml = XMLMapping.load(res.data);
      var guests  = XMLMapping.tojson(xml);
      this.setState({guests: guests});
    });
  }


The results of the json in console:

Object{
  dataset{
   record{
    0{
      company{
        $t: "Skippad"
      }
      first_name{
        $t: "Keith"
      }
      last_name{
        $t: "Cook"
      }
    }
    1{
      company{
        $t: "Skippad"
      }
      first_name{
        $t: "Keith"
      }
      last_name{
        $t: "Cook"
      }
    }
   }
  }
}


I'm using this function to map the object and then using a map() within it:

function mapObject(object, callback) {
  return Object.keys(object).map(function (key) {
    return callback(key, object[key]);
  });
}


This is what the final mapping of the data looks like:

{mapObject(this.state.guests, (key, value) =&gt; {
  return &lt;div key={key}&gt;
    {value.record
    .filter(
      (item,index) =&gt; {
        return (
          item.first_name.$t.toLowerCase().includes(this.state.search.toLowerCase())
          //item.last_name.$t.toLowerCase().includes(this.state.search.toLowerCase())
          //item.company.$t.toLowerCase().includes(this.state.search.toLowerCase())
        )
      }
    )
    .map((item,index) =&gt; {
      return &lt;div className="columns is-mobile" key={index}&gt;
        &lt;div className="column" key={index}&gt;{item.first_name.$t} {item.last_name.$t} &lt;span class="is-hidden-tablet"&gt;&lt;br /&gt;{item.company.$t}&lt;/span&gt;&lt;/div&gt; 
        &lt;div className="column is-hidden-mobile" &gt;{item.company.$t}&lt;/div&gt;
        &lt;div className="column is-hidden-mobile"&gt;
          &lt;EmailFormdisplay guestid={index} /&gt;
        &lt;/div&gt;
        &lt;div className="column is-hidden-mobile"&gt;
          &lt;PhoneFormdisplay guestid={index} /&gt;
          &lt;/div&gt;
          &lt;div className="column is-hidden-tablet is-one-third-mobile"&gt;
          &lt;Dropdown&gt;
            &lt;DropdownTrigger&gt;&lt;/DropdownTrigger&gt;
              &lt;DropdownContent&gt;
                &lt;div className="columns"&gt;
                  &lt;div className="column"&gt;
                    &lt;EmailFormdisplay guestid={index} /&gt;
                  &lt;/div&gt;
                  &lt;div className="column"&gt;
                    &lt;PhoneFormdisplay guestid={index} /&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
              &lt;/DropdownContent&gt;
          &lt;/Dropdown&gt;
          &lt;/div&gt;
      &lt;/div&gt;;
    })}
    &lt;/div&gt;
  })}


Is there a better way of doing this without using mapObject() and a map() within it?

Any kind of feedback or advice would be greatly appreciated!
A few things:


I'm not sure why you need to map over the top level object? Are there top-level keys other than dataset that 
you're interested in? From your example, it looks like you only need the array of records (guests), in which case you don't need mapObject.
I usually try to keep JSX expressions as slim as possible. Your JSX is quite long, and I can see 3 opportunities to shorten/simplify it:


Push more of the transformation into componentDidMount, making the data easier to work with during render
If some transformation has to be done during render (e.g. the search filtering), then consider assigning it to an intermediate local variable rather than doing it inline in JSX
Extract smaller components for logical sections

I'm guessing that those commented out lines were meant to be || (or) clauses?
Try naming variables according to the domain model. I.e., guest rather than item.
There's a bit of duplication that can be reduced, like lower-casing the search string.


Here's a complete example (haven't tested it!):

class Guests extends React.Component {
  constructor(props) {
    super(props);
    this.state = { guests: [] };
  }

  componentDidMount() {
    axios.get('https://gist.githubusercontent.com/eMatsiyana/e315b60a2930bb79e869b37a6ddf8ef1/raw/10c057b39a4dccbe39d3151be78c686dcd1101aa/guestlist.xml')
      .then(res =&gt; {
        const xml = XMLMapping.load(res.data);
        const json = XMLMapping.tojson(xml);
        this.setState({ guests: json.dataset.record });
      });
  }

  render() {
    const search = this.state.search.toLowerCase();
    const guests = this.state.guests.filter(guest =&gt; (
      guest.first_name.$t.toLowerCase().includes(search) ||
        guest.last_name.$t.toLowerCase().includes(search) ||
        guest.company.$t.toLowerCase().includes(search)
    ));

    return (
      &lt;div&gt;
        {guests.map((guest, index) =&gt; (
          &lt;div className="columns is-mobile" key={index}&gt;
            &lt;Guest first_name={guest.first_name.$t} last_name={guest.last_name.$t} company={guest.company.$t} /&gt;
            &lt;div className="column is-hidden-mobile" &gt;{guest.company.$t}&lt;/div&gt;
            &lt;div className="column is-hidden-mobile"&gt;
              &lt;EmailFormdisplay guestid={index} /&gt;
            &lt;/div&gt;
            &lt;div className="column is-hidden-mobile"&gt;
              &lt;PhoneFormdisplay guestid={index} /&gt;
            &lt;/div&gt;
            &lt;GuestDropdown index={index} /&gt;
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    );
  }
}

const Guest = ({ first_name, last_name, company }) =&gt; (
  &lt;div className="column"&gt;
    {first_name} {last_name}
    &lt;span class="is-hidden-tablet"&gt;&lt;br /&gt;{company}&lt;/span&gt;
  &lt;/div&gt; 
);

const GuestDropdown = ({ index }) =&gt; (
  &lt;div className="column is-hidden-tablet is-one-third-mobile"&gt;
    &lt;Dropdown&gt;
      &lt;DropdownTrigger /&gt;
      &lt;DropdownContent&gt;
        &lt;div className="columns"&gt;
          &lt;div className="column"&gt;
            &lt;EmailFormdisplay guestid={index} /&gt;
          &lt;/div&gt;
          &lt;div className="column"&gt;
            &lt;PhoneFormdisplay guestid={index} /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/DropdownContent&gt;
    &lt;/Dropdown&gt;
  &lt;/div&gt;
);


Hope that helps :)