Reputation: 11
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
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