Lee Marsden
Lee Marsden

Reputation: 11

React JS display clicked table row

I am currently trying to learn react by building a simple app that works with a JSON array by calling a certain API. I would then like to show the results of the array in a table and have the ability to click one of the rows and get the data from that row to update another part of the page.

I have successfully called the API and am showing the correct data in the table but I am struggling to figure out how to show the data after the click in another part of the page. I created a click handler event and can log information to the console but cant figure out how I would show this data on the page for the relevant row that is clicked.

So I currently have this in my page:

<div class="container"></div>

<script type="text/jsx">

    var ShowData = React.createClass({

          getInitialState: function() {
            return { data: [] };
          },

          componentDidMount: function() {
            $.get(this.props.source, function(data) {
              if (this.isMounted()) {
                this.setState({
                    data: data
                });
              }
            }.bind(this));
          },

          handleClick: function(i) {
            console.log('You clicked: ' + this.state.data[i].event + this.state.data[i].name);
          },

          render: function() {
            var self = this;
            return (
                <table className="m-table">
                    <thead>
                            <tr>
                                <th>Event</th>
                                <th>Name</th>
                            </tr>
                        </thead>
                    <tbody>
                    {this.state.data.map(function(type, i){
                   return (
                        <tr>
                            <td title="Type" onClick={self.handleClick.bind(this, i)} key={i}>{type.event}</td>
                            <td title="Type">{type.name}</td>
                        </tr>
                    )
                })}

                        </tbody>
                    </table>
            );
          }

        });

  React.render(
          <ShowData source="url of api" />,
          document.getElementById('container')
        );

</script>

Below this script is another container that I would like to show the results when the table row is clicked.

So to summarize, I want to display the data from the API call in a table, upon clicking on one of the table rows I want to take the table row data and format it in another container on the page.

Upvotes: 1

Views: 12179

Answers (1)

Markus-ipse
Markus-ipse

Reputation: 7396

I'd move both the table-component and the display area-component into a parent component that has the responsibility of managing state. The parent component will pass a callback for handling row clicks down to the table, something along the lines of the below edits to your code example. (Heads-up: haven't slept in the past 40+ hours when writing this, due to travel..)

<div class="container"></div>

<script type="text/jsx">

    var TableComponent = React.createClass({   
          handleClick: function(i) {
             this.props.clickHandler(i);
          },

          render: function() {
            var self = this;
            return (
                <table className="m-table">
                    <thead>
                            <tr>
                                <th>Event</th>
                                <th>Name</th>
                            </tr>
                        </thead>
                    <tbody>
                    {this.props.data.map(function(type, i){
                   return (
                        <tr>
                            <td title="Type" onClick={self.handleClick.bind(this, i)} key={i}>{type.event}</td>
                            <td title="Type">{type.name}</td>
                        </tr>
                    )
                })}

                        </tbody>
                    </table>
            );
          }

        });

  var DetailsArea = React.createClass({
      render: function() {
          var rowDetails = this.props.rowDetails;

          return <div>{rowDetails.name}</div>;
      }
  });

  var ParentComponent = React.createClass({
      getInitialState: function() {
          return {data: []};
      },

      componentDidMount: function() {
          $.get(this.props.source, function(data) {
            if (this.isMounted()) {
              this.setState({
                  data: data
              });
            }
          }.bind(this));
       },

       rowClickHandler: function(rowIndex) {
           this.setState({selectedRow: rowIndex});
       },

       render: function() {
           var tableData = this.state.data;
           return (
               <TableComponent data={tableData} clickHandler={rowClickHandler} />
               <DetailsArea rowDetails={tableData[this.state.selectedRow]} />
       }
  });

  React.render(
          <ParentComponent source="url of api" />,
          document.getElementById('container')
        );

</script>

Upvotes: 1

Related Questions