Generating a table based on an array of objects
TL;DR Fully functionnal example :



//Columns defines table headings and properties to be placed into the body
const columns = [{ heading: 'Name', property: 'name' }, { heading: 'Age', property: 'age' }, { heading: 'Sex', property: 'sex' }, { heading: 'Breed', property: 'breed' },]

//Data is the array of objects to be placed into the table
const data = [{ name: 'Sabrina', age: '6', sex: 'Female', breed: 'Staffordshire' }, { name: 'Max', age: '2', sex: 'Male', breed: 'Boxer' }]

const App = props =&gt; &lt;Table columns={columns} data={data} propertyAsKey='name' /&gt;

const Table = ({ columns, data, propertyAsKey }) =&gt; 
    &lt;table className='table'&gt;
        &lt;thead&gt;
            &lt;tr&gt;{columns.map(col =&gt; &lt;th key={`header-${col.heading}`}&gt;{col.heading}&lt;/th&gt;)}&lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
            {data.map(item =&gt;
                &lt;tr key={`${item[propertyAsKey]}-row`}&gt;
                    {columns.map(col =&gt; &lt;td key={`${item[propertyAsKey]}-${col.property}`}&gt;{item[col.property]}&lt;/td&gt;)}
                &lt;/tr&gt;
            )}
        &lt;/tbody&gt;
    &lt;/table&gt;
    
ReactDOM.render(&lt;App/&gt;, document.getElementById('root'))
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"&gt;&lt;/script&gt;
&lt;div id='root'&gt;






The main thing that would highly reduce this code is the map function. This function can be applied on an array, execute a callback on every item in the array and returns a new array.

By using it you can reduce the following code :

let headerRow = [];

columns.forEach(col =&gt; {
    headerRow.push(
        &lt;th key={`header-${col.heading}`}&gt;{col.heading}&lt;/th&gt;
    );
});


Can be reduced to this with the exact same result :

const headerRow = columns.map(col =&gt; &lt;th key={`header-${col.heading}`}&gt;{col.heading}&lt;/th&gt;)


You can now include this function directly into your JSX :

&lt;thead&gt;
    &lt;tr&gt;{columns.map(col =&gt; &lt;th key={`header-${col.heading}`}&gt;{col.heading}&lt;/th&gt;)}&lt;/tr&gt;
&lt;/thead&gt;


And the same thing with nested mapping for the body :

&lt;tbody&gt;
    {data.map(item =&gt; 
        &lt;tr key={`${item[key]}-row`}&gt;
            {columns.map(col =&gt; &lt;td key={`${item[key]}-${col.property}`}&gt;{item[col.property]}&lt;/td&gt;)}
        &lt;/tr&gt;
    )}
&lt;/tbody&gt;


Your full buildTable function is now reduced to the following :

buildTable = (columns, data, key) =&gt; {
    return (
        &lt;&gt;
            &lt;thead&gt;
                &lt;tr&gt;{columns.map(col =&gt; &lt;th key={`header-${col.heading}`}&gt;{col.heading}&lt;/th&gt;)}&lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                {data.map(item =&gt; 
                    &lt;tr key={`${item[key]}-row`}&gt;
                        {columns.map(col =&gt; &lt;td key={`${item[key]}-${col.property}`}&gt;{item[col.property]}&lt;/td&gt;)}
                    &lt;/tr&gt;
                )}
            &lt;/tbody&gt;
        &lt;/&gt;
    );
};


If you want to go a little further you can also delete this function and embed this code in your render function JSX. I will also convert your component into a stateless function, since you are not using any state value :

const Table = ({ columns, data, propertyAsKey }) =&gt; //Deconstructs your props
    &lt;table className='table'&gt;
        &lt;thead&gt;
            &lt;tr&gt;{columns.map(col =&gt; &lt;th key={`header-${col.heading}`}&gt;{col.heading}&lt;/th&gt;)}&lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
            {data.map(item =&gt;
                &lt;tr key={`${item[propertyAsKey]}-row`}&gt;
                    {columns.map(col =&gt; &lt;td key={`${item[propertyAsKey]}-${col.property}`}&gt;{item[col.property]}&lt;/td&gt;)}
                &lt;/tr&gt;
            )}
        &lt;/tbody&gt;
    &lt;/table&gt;


(You may add brackets and a return statement after the arrow sign, its up to you)

It is also not required to have a fragment as a parent element in your render, as long as there is a single element, it is fine :

class App extends React.Component {
  render() {
    return (
        &lt;Table
          columns={columns}
          data={data}
          propertyAsKey='name' //The data property to be used as a key
        /&gt;
    );
  }
}


Your App component could also be converted to a stateless component:

const App = props =&gt; &lt;Table columns={columns} data={data} propertyAsKey='name' /&gt;