简体   繁体   中英

ReactJS - Set unique state for dynamically generated items

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!

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
   }
 })
}

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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM