1

I am trying to create a Table using React and React-Bootstrap that has a custom number of table rows. The table is supposed to store data about player statistics of a certain video game, and based on the video game the statistics may change, thus the number of rows and titles of these rows must be able to dynamically change as well. I wanted to create an array in the state that held the list of current statistics, then map this array to a element using the map function and render the table. However, after trying several approaches I can't get any of the custom input to render. Below is the code :

Class Structure

class Statistics extends Component {
  constructor(props) {
    super(props)
    this.state = {
      game: '',
      player_names: [],
      positions: [],
      stat_categories: [
        'kills',
        'deaths',
        'assists'
      ]
    }
  }

  renderTableRows(array) {
    return (
      <tr>
        <th> NAME </th>
        <th> TEAM </th>
        <th> POSITION </th>
        { array.map(item => {
            console.log(item)
            <th key={item}> {item} </th>
          })
        }
      </tr>
    )
  }

  render() {
    const columnLength = this.state.player_names.length
    const statCols = this.state.stat_categories

    return (
      <div>
        <MyNav url={this.props.location.pathname} />
        <Table responsive striped bordered hover>
          <thead>
            { this.renderTableRows(statCols) }
          </thead>
        </Table>
      </div>
    )
  }
}

The console also properly logs the data in state (kills, deaths, assists) -- so the issue is when rendering the element. Any help would be appreciated!

1
  • Welcome to StackOverflow, in order to increase readability refrain from sharing images with code, paste the relevant code in the question and format it properly. Commented Jul 5, 2018 at 17:52

4 Answers 4

4

You have no return statement in your map function, inside of renderTableRows.

When using ES6 arrow functions, you can either:

  • Return data directly without a return statement

    (args) => (returnedData);
    
  • Or add some logic instead of just returning directly,

    (args) => {
      // Logic here
    
      return returnedData
    }
    

In the second case you'll need a return statement, because you are logging, if you choose to remove logging, go the first way.

Also, please post the code directly in your question, as using an image makes it less readable and not indexed by search engines.

Sign up to request clarification or add additional context in comments.

2 Comments

Geez... I was scratching my head for a little while there; that got it working. Thanks for the catch! Still new to React and SO - will keep the code formatting in mind for future reference :). Have a good one.
No worries, ES6 can be a bit weird, with its implicit returns, optional parentheses etc..at first!
4

You have to render each item in separate trs, not as a series of ths

renderTableCols(array) {
  return array.map(item => <th>{item}</th>)
}

renderTableColValues(item, cols) {
  return cols.map(col => <td>{item[col]}</td>)
}

renderTableRows(array) {
  return array.map(item =>
    <tr>
      <td>{item.name}</td>
      <td>{item.team}</td>
      <td>{item.position}</td>
      {this.renderTableColValues(item, this.cols)}
    </tr>
  );
}

render() {
  return (
    <Table>
      <thead>
        <tr>
          <th>NAME</th>
          <th>TEAM</th>
          <th>POSITION</th>
          {this.renderTableCols(this.cols)}
        </tr>
      </thead>
      <tbody>
        {this.renderTableRows(items)}
      </tbody>
    </Table>
  );
}

More on tables https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table

Comments

1

I will give you a similar answer of what youre encoutering but its kinda different approach with a excelent solution

So, you are trying to create a dynamic table but youre making table rows static, what i did was letting the table to receive arrays of head and data and then create as many rows or datas that are required.

heres the code

export function objectIntoTableData(object) {
 return Object.values(object).map((data, index) => {
   return  <td key={index}>{data}</td>;
  });
}

You must change this index to (value,index) => , thats just my use

tableRows(data) {
 return data.map(value => {
   return <tr key={value.index}>{objectIntoTableData(value)}</tr>;
 });
}
<thead>
  <tr>
    {head.map((value, index) => {
      return <th key={index}>{value}</th>;
    })}
 </tr>
</thead>
<tbody>{this.tableRows(data)}</tbody>

Rather use a id or index inside your object since the index callback of the map function, its unsafe to use for the keys.

 <ReactTableUse 
     head={["#", "Cell1", "Cell2", "Cell3"]}
     data={[{id:1, test:1},{id:2, test:2}]} 
 />

Comments

0

Rules: When your state changes, render method of a class based component will be called. Question: Who will change the state? will it grow inside the component ? What is your problem ? your are not being able to render anything ? or statistics is not dynamically rendering ? if you want to change it dynamically , you need to change the state first.

1 Comment

The issue was that nothing was rendering at all, and it was because I had forgotten a return statement inside of my map function. I was mapping to the correct elements but not returning anything afterward.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.