Reputation: 235
I am fetching some data from the server to populate a list of items, and each item got a onClick event binded to the items id, that changes the UI to be disabled when clicked.
My problem is that the UI changes to disabled perfectly on the first click, but when I go on to click on the next item it resets the first on, so there is only one button disabled at a time. How do I make it so I can disable all the items I want, without resetting the previous ones?
Here is my component:
class Video extends Component {
constructor () {
super()
this.state = {
isDisabled: false
}
}
handleClick(frag, voted, event){
event.preventDefault()
this.setState({
isDisabled: {
[frag]: true
}
})
}
Snippet of what I return in the UI that changes the disabled button
<button onClick={this.handleClick.bind(this, frags.id, frags.voted)} disabled={this.state.isDisabled[frags.id]} className="rating-heart-2">
<i className="fa fa-heart" aria-hidden="true"></i>
</button>
I would really appreciate all tips!
Upvotes: 0
Views: 787
Reputation: 3009
The code you provided is a bit confusing because in the jsx you have this.state.hasRated
to disable the button and in the handleClick you have a isDisabled
object.
I followed the jsx approach and I add the frag id the hasRated
object with the value true to disable a button each it is clicked.
You can run the following snippet to see the output of the code:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
frags: [],
hasRated: {}
};
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
setTimeout(() => {
this.setState({
frags: [{
id: 1,
voted: false
}, {
id: 2,
voted: false
}, {
id: 3,
voted: false
}]
});
}, 500);
}
handleClick(id, voted) {
return (event) => {
this.setState({
hasRated: {
...this.state.hasRated,
[id]: true
}
});
}
}
render() {
const items = this.state.frags.map(frag => ( <
button
key={frag.id}
onClick = {
this.handleClick(frag.id, frag.voted)
}
disabled = {
this.state.hasRated[frag.id]
}
className = "rating-heart-2" >
Button <
/button>
));
return (
<div>
{items}
</div>
);
}
}
ReactDOM.render( < Example / > , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="container"></div>
Upvotes: 0
Reputation: 2701
It seems that when you call setState, you are overriding the previous value of the isDisabled
.
You can do something like this:
handleClick(frag, voted, event){
event.preventDefault()
this.setState({
isDisabled: {
...this.state.isDisabled,
[frag]: true
}
})
}
Upvotes: 1