conquester
conquester

Reputation: 1132

React not displaying data in table row

I am a beginner to React and frontend development in general. Here is a "simple" code to display a table.

function TableHeader() { 
    return (
        <thead>
            <tr>
                <th>Name</th>
                <th>Job</th>
            </tr>
        </thead>
    );
  }


function TableDataRow(row, index) {
    return (
        <tr key={index}>
            <td>{row.name}</td>
            <td>{row.job}</td>
        </tr>
    )
}


function TableBody(props) { 
    const characterData = props.characterData;
    return (
        <tbody>
            {characterData.map((row, index) => <TableDataRow row={row} index={index}/>)}
        </tbody>
    );
  }



class Table extends Component {
    render() {
        const { characterData } = this.props;

        return (
            <table>
                <TableHeader />
                <TableBody characterData={characterData} />
            </table>
        );
    }
}

class App extends Component {
  render() {
    const characters = [
      {
          'name': 'Charlie',
          'job': 'Janitor'
      },
      {
          'name': 'Mac',
          'job': 'Bouncer'
      },
      {
          'name': 'Dee',
          'job': 'Aspring actress'
      },
      {
          'name': 'Dennis',
          'job': 'Bartender'
      }
  ];

  return (
    <div className="container">
       <Table characterData={characters} />
    </div>
    );
  }
}

The error is as follows:

Warning: Each child in a list should have a unique "key" prop.

Check the render method of TableBody. See https://banned-fb.example.com/react-warning-keys for more information. in TableDataRow (at Table.js:30) in TableBody (at Table.js:44) in table (at Table.js:42) in Table (at App.js:28) in div (at App.js:27) in App (at src/index.js:6)

The data rows are empty in the table. I think there is an issue in the call to TableDataRow. What is that I am possibly doing wrong?

Screenshot:

enter image description here

Upvotes: 2

Views: 3729

Answers (2)

user11043998
user11043998

Reputation:

import React from 'react';
function TableHeader() {
  return (
    <thead>
      <tr>
        <th>Name</th>
        <th>Job</th>
      </tr>
    </thead>
  );
}


function TableBody(props) {
  const characterData = props.characterData;

  return (<tbody>
    {characterData.map((row, index) =>
      <tr key={index}>
        <td>{row.name}</td>
        <td>{row.job}</td>
      </tr>)}
  </tbody>
  );
}



class Table extends React.Component {
  render() {
    const { characterData } = this.props;

    return (
      <table>
        <TableHeader />
        <TableBody characterData={characterData} />
      </table>
    );
  }
}

class Hello extends React.Component {
  render() {
    const characters = [
      {
        'name': 'Charlie',
        'job': 'Janitor'
      },
      {
        'name': 'Mac',
        'job': 'Bouncer'
      },
      {
        'name': 'Dee',
        'job': 'Aspring actress'
      },
      {
        'name': 'Dennis',
        'job': 'Bartender'
      }
    ];

    return (
      <div className="container">
        <Table characterData={characters} />
      </div>
    );
  }
}
export default Hello;

Find your working solution here..

Stackblitz Link

Upvotes: 1

Vaibhav Vishal
Vaibhav Vishal

Reputation: 7108

Key thing is just a warning, but you should fix it too, the reason nothing is rendering because you have your component like this:

function TableDataRow(row, index) {...}  // WRONG

Function Component get just one argument that is props, what you need to do is either:

function TableDataRow(props) {
    const {row, index} = props;  // get row and index out of props inside function
    ... 
}

OR

function TableDataRow({ row, index }) {...}  // destructure the props in parameter


Now About fixing the key warning:
Instead of providing key to the <tr> inside TableDataRow you need to provide key to TableDataRow, like this:

function TableDataRow({ row }) { // you have a little error here too, row should be inside curly braces or use props and get row from props inside the function
  return (
    <tr>  // no need of key
        <td>{row.name}</td>
        <td>{row.job}</td>
    </tr>
  )
}


function TableBody(props) { 
  const characterData = props.characterData;
  return (
    <tbody>
        {characterData.map((row, index) => <TableDataRow row={row} key={index}/>)}  // key should be here
    </tbody>
  );
}

Also you should use index as key as last resort (see docs for why). If your data comes from api every item might have an id you can use that as key, or there is maybe something else unique for each character, if not, it's ok to use index.

Upvotes: 2

Related Questions