Reputation: 2467
React newbie here.
Not sure why but these onclick events are not firing for me.
I'm importing this class into a main class so maybe my main class can't read the functions inside or something?
var React = require('react');
import { Button } from 'semantic-ui-react'
class TableDataRow extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
const item = this.props.item;
var columns = Object.keys(item).map(function(key) {
return <td value={key}>{item[key]}</td>
});
return (
<tr>
{columns}
<td>
<button className="ui button edit blue" value="{item.id}">
<i className="edit icon"></i>
</button>
</td>
<td>
<button onClick={this.handleClick} className="ui button delete red" value="{item.id}">
<i className="delete icon"></i>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
</td>
</tr>
);
}
}
module.exports = TableDataRow;
Upvotes: 1
Views: 865
Reputation: 3451
var React = require('react');
import { Button } from 'semantic-ui-react'
class TableDataRow extends React.Component {
// you don't need constructor just for initial states
state = {isToggleOn: true};
// Use arrow function and get lexical binding
handleClick = () => {
this.setState({isToggleOn: !this.state.isToggleOn})
}
render() {
// Do object destructuring, so from now on
// item will be referred to this.props.item
const {item} = this.props;
const {isToggleOn} = this.state;
return (
<tr>
{ Object.keys(item).map(key => <td value={key}>{item[key]}</td>) }
<td>
<button className="ui button edit blue" value={item.id}>
<i className="edit icon"></i>
</button>
</td>
<td>
<button onClick={this.handleClick} className="ui button delete red" value={item.id}>
<i className="delete icon"></i>
{isToggleOn ? 'ON' : 'OFF'}
</button>
</td>
</tr>
);
}
}
module.exports = TableDataRow;
Using arrow function creates lexical binding, which means it is always binded to where it was defined, that way you don't need to bind it in constructor - cleaner code.
This article explains all the different ways of handling 'this'
When you do var item = this.props.item
, you're creating another copy of item. This can be achieved through destructuring: const {item} = this.props
. Notice how I also destructured isToggleOn
.
Simple intro to object destructuring
Lastly using .map
and arrow function you can achieve some really clean code as shown above.
Upvotes: 1
Reputation: 698
You forgot to bind the handleClick to this:
<button onClick={this.handleClick.bind(this)} className="ui button delete red" value="{item.id}">
<i className="delete icon"></i>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
Upvotes: 0
Reputation: 527
Try using
this.setState(({prevState}) => ({
isToggleOn: !prevState.isToggleOn
});
instead of
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
Upvotes: 0