更改为 React State 不会更新功能组件中的显示 [英] Change to React State doesn't update display in functional component
问题描述
我创建了一个简单的 2 组件应用,其中动物的名称显示了动物的图标,以概括我在更复杂的应用中遇到的问题.
一旦随机选择一个动物并合并到 state
中,Display
组件应该重新渲染,并且 animalIcon
也应该更新,因为 state
是通过 props
传递的(或者我是这么认为的).
相反,我们被困在第一个动物的图标上(随机选择).
我真的很想知道为什么图标没有更新,因为我认为当 state
改变时,它会重新渲染使用该信息的组件(在这种情况下,Display
组件),并且 console.log(animalIcon)
正确地向我展示了在每次重新渲染 Display
组件时,animalIcon
正确分配了正确的元素/图标.
唯一不变的是Display
组件的return
语句中{animalIcon}
的输出.强>
class App extends React.Component {构造函数(道具){超级(道具);this.state = {当前动物:''}this.getAnimal = this.getAnimal.bind(this);}获取动物(){函数 getRandomAnimal(arr) {函数 getRandomIndex(min, max) {min = Math.ceil(min);max = Math.floor(max);返回 Math.floor(Math.random() * (max - min + 1)) + min;}返回 arr[getRandomIndex(0, arr.length - 1)];}const allAnimals = ['cat', 'dog', 'mouse'];const selectedAnimal = getRandomAnimal(allAnimals);this.setState({currentAnimal: selectedAnimal});}使成为() {返回(<Display getAnimal={this.getAnimal}animal={this.state.currentAnimal}/>)}}功能展示(道具){常量图标 = {猫:<i class="fas fa-cat"></i>,狗:<i class="fas fa-dog"></i>,鼠标:<i class="fas fa-mouse-pointer"></i>,}让animalIcon = 图标[props.animal.toLowerCase()];控制台日志(动物图标);返回 (<div><h1>{props.animal} 看起来像 {animalIcon}</h1><button onClick={props.getAnimal}>获取新动物</button>
)}ReactDOM.render(
<script src="https://use.fontawesome.com/releases/v5.5.0/js/all.js"></脚本><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 class="root"></div>
您可以使用属性 key ,当您传递道具时,它似乎没有正确更新.如果动物名称更改,这将告诉 react 更新图标.
{动物图标}</span>
class App extends React.Component {构造函数(道具){超级(道具);this.state = {当前动物:''}this.getAnimal = this.getAnimal.bind(this);}获取动物(){函数 getRandomAnimal(arr) {函数 getRandomIndex(min, max) {min = Math.ceil(min);max = Math.floor(max);返回 Math.floor(Math.random() * (max - min + 1)) + min;}返回 arr[getRandomIndex(0, arr.length - 1)];}const allAnimals = ['cat', 'dog', 'mouse'];const selectedAnimal = getRandomAnimal(allAnimals);this.setState({currentAnimal:选择的动物});}使成为() {返回 ( <显示 getAnimal = {this.getAnimal}动物 = {this.state.currentAnimal}/>)}}功能显示(道具){常量图标 = {猫:<i class = "fas fa-cat" ></i>,狗:<i class = "fas fa-dog" ></i>,鼠标:,}让animalIcon = 图标[props.animal.toLowerCase()];控制台日志(道具.动物);返回 ( <div ><h1> {道具.动物}看起来像 <span key={props.animal}>{动物图标}</span></h1><按钮点击 = {props.getAnimal} >获取新动物 按钮></div>)}ReactDOM.render( < App/> , document.querySelector('.root'));
<script src="https://use.fontawesome.com/releases/v5.5.0/js/all.js"></脚本><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 class="root"></div>
I created a simple, 2 component app where the name of the animal shows the icon of the animal to generalize an issue I am having in a more complicated app.
Once a random animal is selected and merged into state
, the Display
component should re-render, and the animalIcon
should also update, since state
is being pass down through props
(or so I thought).
Instead, we are stuck on icon of whatever the first animal is (randomly chosen).
I would really like to know why the icon doesn't update, since I thought when state
is changed, it will re-render the components that use that piece of information (in this case, the Display
component), and console.log(animalIcon)
is correctly showing me that on every re-render of the Display
component, that the animalIcon
is correctly being assigned the right element/icon.
The only thing not changing is the output of {animalIcon}
in the return
statement of the Display
component.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
currentAnimal: ''
}
this.getAnimal = this.getAnimal.bind(this);
}
getAnimal() {
function getRandomAnimal(arr) {
function getRandomIndex(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
return arr[getRandomIndex(0, arr.length - 1)];
}
const allAnimals = ['cat', 'dog', 'mouse'];
const chosenAnimal = getRandomAnimal(allAnimals);
this.setState({currentAnimal: chosenAnimal});
}
render() {
return(
<Display getAnimal={this.getAnimal} animal={this.state.currentAnimal}/>
)
}
}
function Display (props) {
const icons = {
cat: <i class="fas fa-cat"></i>,
dog: <i class="fas fa-dog"></i>,
mouse: <i class="fas fa-mouse-pointer"></i>,
}
let animalIcon = icons[props.animal.toLowerCase()];
console.log(animalIcon);
return (
<div>
<h1>{props.animal} looks like {animalIcon}</h1>
<button onClick={props.getAnimal}>Get New Animal</button>
</div>
)
}
ReactDOM.render(<App />, document.querySelector('.root'));
<script src="https://use.fontawesome.com/releases/v5.5.0/js/all.js"></script>
<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 class="root"></div>
You can wrap the animalIcon
with attribute key , as you are passing props it seems its not updating correctly. This will tell react to update the icon if animal name is changed.
<span key={props.animal}>{
animalIcon
}</span>
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
currentAnimal: ''
}
this.getAnimal = this.getAnimal.bind(this);
}
getAnimal() {
function getRandomAnimal(arr) {
function getRandomIndex(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
return arr[getRandomIndex(0, arr.length - 1)];
}
const allAnimals = ['cat', 'dog', 'mouse'];
const chosenAnimal = getRandomAnimal(allAnimals);
this.setState({
currentAnimal: chosenAnimal
});
}
render() {
return ( <
Display getAnimal = {
this.getAnimal
}
animal = {
this.state.currentAnimal
}
/>
)
}
}
function Display(props) {
const icons = {
cat: < i class = "fas fa-cat" > < /i>,
dog: < i class = "fas fa-dog" > < /i>,
mouse: < i class = "fas fa-mouse-pointer" > < /i>,
}
let animalIcon = icons[props.animal.toLowerCase()];
console.log(props.animal);
return ( <div ><h1> {
props.animal
}
looks like <span key={props.animal}>{
animalIcon
}</span> < /h1> <
button onClick = {
props.getAnimal
} > Get New Animal < /button> <
/div>
)
}
ReactDOM.render( < App / > , document.querySelector('.root'));
<script src="https://use.fontawesome.com/releases/v5.5.0/js/all.js"></script>
<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 class="root"></div>
这篇关于更改为 React State 不会更新功能组件中的显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!