Reputation: 107
In my hangman game, the player can click a letter(button) and the guessed letter shows if correct it is appended to the hidden word (_ _ _ _ )
but I would like to refactor a long list of buttons into a simple map function that creates a button for every letter in the array (i.e the Alphabet) ideally, the button would disappear after it has been clicked.
something like:
arr = [alphabet]
arr.map(letter=>{
return <button>{letter}</button>
})
but I can't figure out how to convert my list into such a function
export class Input extends Component {
handleClick = (event) => {
if (this.props.guesses.includes(event.target.value)) {
} else {
this.props.makeGuess(event.target.value.toLowerCase())
}
// event.target.setAttribute('disabled', '')
}
render() {
return (<div>
<button onClick={this.handleClick} value="A">A</button>
<button onClick={this.handleClick} value="B">B</button>
<button onClick={this.handleClick} value="C">C</button>
<button onClick={this.handleClick} value="D">D</button>
<button onClick={this.handleClick} value="E">E</button>
<button onClick={this.handleClick} value="F">F</button>
<button onClick={this.handleClick} value="G">G</button>
<button onClick={this.handleClick} value="H">H</button>
<button onClick={this.handleClick} value="I">I</button>
<button onClick={this.handleClick} value="J">J</button>
<button onClick={this.handleClick} value="K">K</button>
<button onClick={this.handleClick} value="L">L</button>
<button onClick={this.handleClick} value="M">M</button>
<button onClick={this.handleClick} value="N">N</button>
<button onClick={this.handleClick} value="O">O</button>
<button onClick={this.handleClick} value="P">P</button>
<button onClick={this.handleClick} value="Q">Q</button>
<button onClick={this.handleClick} value="R">R</button>
<button onClick={this.handleClick} value="S">S</button>
<button onClick={this.handleClick} value="T">T</button>
<button onClick={this.handleClick} value="U">U</button>
<button onClick={this.handleClick} value="V">V</button>
<button onClick={this.handleClick} value="W">W</button>
<button onClick={this.handleClick} value="X">X</button>
<button onClick={this.handleClick} value="Y">Y</button>
<button onClick={this.handleClick} value="Z">Z</button>
</div>)
}
}
Upvotes: 0
Views: 1796
Reputation: 103
Here's an example of how to iterate over your array of letters and output a button for each of them:
export class Input extends Component {
const handleClick = e => {
// Your logic here...
};
const alphabet = [ // Letters of the alphabet... ];
const buttons = alphabet.map(letter => (
<button value={letter} onClick={handleClick}>
{letter}
</button>
));
return <div>{buttons}</div>;
}
Upvotes: -1
Reputation: 1631
Your render method should be:
render() {
const alphabet = [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'];
return (
<div>
{alphabet.map((letter, index) => <button key={} onClick={this.handleClick} value={letter}>{letter}</button>)}
</div>
);
}
Upvotes: 2
Reputation: 947
Here is an example of a complete component that filters the letters out:
export class Input extends Component {
constructor() {
super()
this.state = {
letters: [/* the letters */],
}
}
handleClick = letter => () => {
this.props.makeGuess(letter.toLowerCase())
this.setState({ letters: this.state.letters.filter(l => l !== letter) })
}
render() {
return (<div>
{this.state.letters.map(letter =>
<button key={letter} onClick=this.handleClick(letter)>{letter}</button>
)}
</div>
}
}
This example initializes state with all of the letters then uses currying to create a custom click handler for each button based on the letter passed in. The functions filter out their letter and update state causing a re-render without that letter. This way there is no need to use value or deal with the event at all.
Upvotes: 0
Reputation: 2759
You can simply have a function scoped under render
that creates the array of elements you want to render. Try this:
export class Input extends Component {
render() {
function buttonList() {
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
return alphabet.map(letter => {
return <button onClick={this.handleClick} key={letter}>{letter}</button>
});
}
return (
<div>{buttonList()}</div>
);
}
}
You also need to set the key
value on each of the elements or you will get a React warning.
Upvotes: 0