newDev
newDev

Reputation: 107

How to make my buttons disappear onClick (addclass in (click) event handler?)) (react)

Okay, So The code for my alphabetic buttons in my Hangman game works well, it shows up on the page in the guessed letter section when clicked and if the letter is correct it is appended to and replaces the underscore in the right place (_ _ _ _) My question is: How can I refactor my handleClick(event) in a way that when the button is clicked the button disappears (so maybe by adding a class, set display:none)

 export class Input extends Component {

      handleClick = (event) => {
        if (this.props.guesses.includes(event.target.value)) {
          return this.event.value
        } else {
          return this.props.makeGuess(event.target.value.toLowerCase())
        }
      }
      render() {
        const alphabet = [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'];

        return (<div className="containerAlph">
          {alphabet.map((letter, index) => <button className="AlphaBet" key={index} onClick={this.handleClick} value={letter}>{letter}</button>)}
        </div>);
      }

    }

Upvotes: 0

Views: 1054

Answers (1)

theJuls
theJuls

Reputation: 7460

There are many ways to do this.

I am going to use the state to do so instead of adding a CSS class. Basically you will keep track of the buttons available through the alphabet array. Each time we click on a button, we will remove that letter from the array and re-render the component.

First of all, I would change your alphabet array to be a state property. That way every time you update it, it will be re-rendered and your buttons will disappear accordingly.

So first change, in your render function let us change the alphabet to come from the state:

const { alphabet } = this.state

I declared this in the component's constructor:

constructor (props) {
    super(props)
    this.state = {
      alphabet : [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ']
    }
  }

Now... lets deal with the handleClick function. We want to pass in which letter we are clicking, and remove that letter from the alphabet array. In the return statement when rendering the buttons, make sure to pass in which letter you are removing in the handleClick function.

return (<div className="containerAlph">
        {alphabet.map((letter, index) => <button className="AlphaBet" key={index} onClick={() => this.handleClick(letter)} value={letter}>{letter}</button>)}
      </div>);

Now for the function itself: Grab the value of alphabet state, and remove the letter you clicked on from that state.

this.setState causes the component to re-render, and now that you removed the letter you clicked on, it won't be displayed anymore.

handleClick(letter) {
    const alphabet = [...this.state.alphabet]
    // remove the letter from the state
    const index = alphabet.indexOf(letter)
    if (index > -1) {
      alphabet.splice(index, 1);
    }
    this.setState({ alphabet })
  }

Hope that helps.

Here is a working app:

class App extends React.Component {
  
  constructor (props) {
    super(props)
    
    // set the state alphabet as your array so that
    // we can re-render whenever we update it
    this.state = {
      alphabet : [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ']
    }
  }
  
  handleClick(letter) {
    const alphabet = [...this.state.alphabet]
    // remove the letter from the state
    const index = alphabet.indexOf(letter)
    if (index > -1) {
      alphabet.splice(index, 1);
    }
    this.setState({ alphabet })
  }
  
  render() {
    const { alphabet } = this.state

    return (<div className="containerAlph">
        {alphabet.map((letter, index) => <button className="AlphaBet" key={index} onClick={() => this.handleClick(letter)} value={letter}>{letter}</button>)}
      </div>);
}

}

ReactDOM.render(
    <App />,
    document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Update: as mentioned in the conversation, here is how I think your handleClick should be to incorporate the other stuff you would like to happen:

handleClick = (event, letter) => {
    // First do the stuff to make the button disappear
    const alphabet = [...this.state.alphabet]
    const index = alphabet.indexOf(letter)
    if (index > -1) {
      alphabet.splice(index, 1);
    }
    this.setState({ alphabet })

    // now do the other stuff
    if (this.props.guesses.includes(event.target.value)) {
        return this.event.value
    } else {
        return this.props.makeGuess(event.target.value.toLowerCase())
    }
 }

Now in the render function, we just need to pass in both parameters:

render() {
    const { alphabet } = this.state

    return (<div className="containerAlph">
        {alphabet.map((letter, index) => <button className="AlphaBet" key={index} onClick={(event) => this.handleClick(event, letter)} value={letter}>{letter}</button>)}
      </div>);
}

Upvotes: 2

Related Questions