我创建了一个简单的2组件应用程序,其中动物的名字显示了动物的图标,以概括我在更复杂的应用程序中遇到的问题。
一旦选择了一个随机动物并将其合并到中state,该Display组件应该重新渲染,并且该组件也animalIcon应该更新,因为state正在向下传递props(或者我认为)。
state
Display
animalIcon
props
取而代之的是,我们被卡在任何第一个动物(随机选择)的图标上。
我真的很想知道为什么图标不会更新,因为我认为state更改时间后,它将重新呈现使用该信息的Display组件(在本例中为组件),并在此console.log(animalIcon)正确显示给我。每次重新渲染Display组件时,animalIcon即已正确分配了正确的元素/图标。
console.log(animalIcon)
不改变的唯一的事情就是输出{animalIcon}在return该声明Display的组成部分。
{animalIcon}
return
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>
您可以包装animalIconwith属性key,在传递道具时,它似乎无法正确更新。如果动物名称发生更改,这将告诉用户更新图标的反应。
<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>