Reputation: 25
I have a React component ResultsTable with markup only, and all data fetching is done in its container ResultsTableContainer and passed when rendering.
ResultsTable.jsx
const ResultsTable = ({ games, results }) => (
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn>Date</TableHeaderColumn>
<TableHeaderColumn>City</TableHeaderColumn>
<TableHeaderColumn>Venue</TableHeaderColumn>
<TableHeaderColumn>Host</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
{games.map((game, index) => (
<TableRow key={index} onClick={(index) => results}>
<TableRowColumn>
{moment(game.gameDate).format("YYYY-MM-DD")}
</TableRowColumn>
<TableRowColumn>{game.city}</TableRowColumn>
<TableRowColumn>{game.venueName}</TableRowColumn>
<TableRowColumn>{game.hostName}</TableRowColumn>
</TableRow>
))}
</TableBody>
</Table>
);
export default ResultsTable;
ResultsTableContainer.jsx
class ResultsTableContainer extends Component {
constructor(props) {
super(props);
this.state = {
games: []
};
}
componentDidMount = () => {
axios
.get("public_api/games")
.then(resp => {
this.setState({
games: resp.data
});
})
.catch(console.error);
};
handleClick = (i) => {
console.log('clicked' + i)
};
render() {
return (
<ResultsTable
games={this.state.games}
results={this.handleClick.bind(this)}
/>
);
}
}
export default ResultsTableContainer;
My challenge is to make each table row clickable, that I can get more information when clicked on the row. However writing this way, does not execute function handleClick and from what I have read also is not the best way to do things, as it will create a new function for each row. So my question would be how can I create onClick handler for that would know which row have I clicked? Or what else may I do to make it work? Also, would really appreciate, if you could point me to a good reading about this topic. Thank you!
Upvotes: 0
Views: 82
Reputation: 25
Seems it was related to a bug in Material UI Table component, which I am using. More info: https://github.com/callemall/material-ui/issues/1783 . So I ended up creating button for each row and now everything works.
Upvotes: 0
Reputation: 24660
Since you are already using an arrow function for handleClick
you don't need bind the function again manually. You can just use it as this.handleClick
.
To get the index/id of the row you clicked you can try something like this,
const ResultsTable = ({ games, onRowClick }) => (
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn>Date</TableHeaderColumn>
<TableHeaderColumn>City</TableHeaderColumn>
<TableHeaderColumn>Venue</TableHeaderColumn>
<TableHeaderColumn>Host</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
{games.map((game, index) => (
<TableRow key={index} id={index} onClick={onRowClick}>
<TableRowColumn>
{moment(game.gameDate).format("YYYY-MM-DD")}
</TableRowColumn>
<TableRowColumn>{game.city}</TableRowColumn>
<TableRowColumn>{game.venueName}</TableRowColumn>
<TableRowColumn>{game.hostName}</TableRowColumn>
</TableRow>
))}
</TableBody>
</Table>
);
export default ResultsTable;
class ResultsTableContainer extends Component {
constructor(props) {
super(props);
this.state = {
games: []
};
}
componentDidMount = () => {
axios
.get("public_api/games")
.then(resp => {
this.setState({
games: resp.data
});
})
.catch(console.error);
};
handleClick = (event) => {
// event object from the onClick of the row will be passed
// you can get the index of the row from the event target's id prop
// rather than index, you can use an unique id of some sort too
console.log(`clicked on row ${event.target.id}`);
};
render() {
return (
<ResultsTable
games={this.state.games}
onRowClick={this.handleClick}
/>
);
}
}
export default ResultsTableContainer;
Upvotes: 1