'React component state not updating as expected
In the following code, in the first div of Game.js, the displayed character property "hp" updates when a new input is put in. This is what I want. However in the second div, the rendered value stays at the initial value of 13 even when something is typed in input field of Character.js. How do I fix this? I want to do processing based on the value of HP in Game.js but it's value never seems to update
----------- Game.js -----------------
import React, { Component} from 'react'
import Character from './Character.js';
import './Game.css';
import { v4 as uuidv4 } from "uuid";
class Game extends Component{
state = {
mycharacter : { id: uuidv4(), hp:13},
}
render() {
return (
<>
<div className="grid-container">
// Hp value here updates which is good
<Character key={this.state.mycharacter.id} hp={this.state.mycharacter.hp}/>
</div>
<div>
{this.state.mycharacter.hp}
</div>
</>
);
};
}
export default Game;
--------------- Character.js ---------------
import React, { Component } from 'react'
class Character extends Component{
state = {
hp: this.props.hp,
}
handleInputChange(e) {
const newHp = e.target.value
console.log("old hp is", this.state.hp)
this.setState({
hp: newHp
})
console.log("new hp is", newHp)
}
render() {
return(
<div onChange={(e) => {this.handleInputChange(e)}}>
<input></input>
{this.state.hp}
</div>
)
};
}
export default Character;
Solution 1:[1]
It's widely recommended to store data only in one place, especially in React.
Currently, hp is stored in two components. You change one value but not the second.
To fix this, the common way is to remove
state = {
hp: this.props.hp,
}
Now, just use this.props.hp instead of this.state.hp.
(generally, avoid creating state from props unless strictly necessary)
In Game, you could initialize a method
setHp(hp) {this.setState({hp});}
and pass it to Character as <Character setHp={this.setHp} ...
Finally, in Character, instead of
this.setState({
hp: newHp
})
use
this.props.setHp(newHp)
It would ensure that your hp data is stored in one place. Generally, never duplicate data if not necessary, because it leads to a plethora of issues.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Igor Loskutov |
