Hello! I’m new to React and I’ve been trying to update a component’s (guessed) state via a method, but It’s not changing at all when I check React devtools. Interestingly enough, if I move the guessed setState call to the displayLetters method and delete the rest, it works perfectly fine. I’m calling multiple setStates, so I tried using promises as I thought it was an async thing but haven’t had any luck. Thank you for any help you may provide.
Relevant Code:
state = {
word: 'cat',
revealed: '',
guessed: [],
urls: ['./hangman5.png','./hangman4.png','./hangman3.png','./hangman2.png','./hangman1.png', './hangman0.png'],
currentManURL: '',
lives: 5,
testCount: 0
}
constructor(props){
super(props);
}
displayMan = () => {
this.setState(()=>({currentManURL: this.state.urls[this.state.lives]}));
}
incrementTest = () => {
this.setState(()=> ({testCount: 4}));
}
handleGuess = (guess) => {
if(this.state.guessed.indexOf(guess)>-1){
return 'Already guessed'
}
else if (guess.length > 1 || guess.length === 0){
return 'Enter one letter guesses.'
}
else if(this.state.word.includes(guess)){
this.setState((prevState)=>(({guessed: prevState.guessed.concat([guess])})));
this.displayLetters();
}
else{
this.setState((prevState)=>({lives: prevState.lives-1}))
console.log(this.state.lives)
if(this.state.lives===0){
alert('You lost!')
}else{
this.displayMan();
}
this.setState((prevState)=>(({guessed: prevState.guessed.concat([guess])})));
}
this.setState((prevState)=>(({guessed: prevState.guessed.concat([guess])})));
}
displayLetters = () => {
let reveal = '';
for(let i = 0; i < this.state.word.length; i++){
if(this.state.guessed.includes(this.state.word.charAt(i))){
reveal+=this.state.word.charAt(i);
}
else{
reveal+='_ '
}
}
//Inserting the set state here makes it work, not sure why.
this.setState(() => ({revealed:reveal}))
}
setUpRevealed = () => {
let str = ''
for(let i = 0; i < this.state.word.length; i++){
str+='_ ';
}
this.setState(()=> ({revealed: str}));
}
render() {
return (
<div>
<Header />
<Man
man = {this.state.currentManURL}
lives = {this.state.lives}
displayMan={this.displayMan}
setUpRevealed={this.setUpRevealed}
testCount = {this.state.testCount}
incrementTest={this.incrementTest}
revealed ={this.state.revealed}
/>
<WordForm
handleGuess = {this.displayLetters}
/>
<Word revealed ={this.state.revealed}/>
</div>
);
}
}
export default Hangman;
//Component where I intended returned err value to be used:
export default class WordForm extends React.Component {
state = {
error: undefined
}
constructor(props){
super(props);
}
handleGuess = (e) => {
e.preventDefault();
const guess = e.target.elements.guessInput.value.trim();
const error = this.props.handleGuess(guess);
this.setState(()=> ({error}))
if(!error){
e.target.elements.guessInput.value = '';
};
}
render(){
return (
<div>
{this.state.error && <p>{this.state.error}</p>}
<form onSubmit={this.handleGuess}>
<label htmlFor="guessInput">Enter Guess: </label>
<input name="guessInput" type="text"></input>
<button type="submit">Submit</button>
</form>
</div>
);
}
}