1

I have multiple buttons that are rendered for multiple items. All the buttons have a unique id that I passed to the key, and I'm trying to disable the button based on the unique ID. The disable boolean is in the state, and when the button is clicked I want it to disable that one unique button.

However, the code I have disables all of the buttons that are rendered.

I've used map to access the parks items array in my state, so I'm not sure how I'd map over the buttons if I turned them into an array with unique keys in the state.

Here's what I have so far:

My state:

this.state = {
  parks: [],
  todos: [],
  disabled: false
};

The button:

<button
 key={item.id} //this id is coming from the mapped array "parks" state
 disabled={this.state.disabled}
 onClick={() =>
    this.setState({
    todos: [...this.state.todos, item.name], //this adds the parks 
                                             //state items to the todos 
                                             //state array
    disabled: true
      })
    }
  >

2 Answers 2

5

You can achieve it by making the disabled state into arrays that contains the items' id.

Then in line disabled={this.state.disabled.indexOf(item.id)!==-1}, it checks whether the current button exists in the disabled array, .indexOf method returns -1 if the value to search for never occurs.

class TodoApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    	parks: [
      	{id: 'a', name: "Learn JavaScript" },
        { id: 'b',name: "Learn React" },
        { id: 'c',name: "Play around in JSFiddle"},
        {id: 'd', name: "Build something awesome" }
      ],
      todos: [],
      disabled: [],
    }
  }
  
  render() {console.log('todos', this.state.todos)
    return (
      <div>
        <h2>Todos:</h2>      
        {this.state.parks.map(item => (
          <button
           key={item.id} //this id is coming from the mapped array "parks" state
           disabled={this.state.disabled.indexOf(item.id)!==-1}
           onClick={() =>
              this.setState({
                  todos: [...this.state.todos, item.name], 
                  disabled: [...this.state.disabled, item.id]
                })
              }
          >
            {item.name}
          </button>
        ))}
   
      </div>
    )
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

Sign up to request clarification or add additional context in comments.

Comments

0

Instead of using a boolean, you can use an array, where you keep track of the ids that you want to have disabled (= that you clicked on).

In the onClick handler, you add the id of the button to the disabled array within state. For the buttons, you then just check if the item.id is in the this.state.disabled array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.