人。我可能有一个菜鸟问题,不过我还是会射击。下面的代码段非常简单,我不应该遇到问题,但是我们开始吧。我正在尝试获取ColorsGrid
组件中的颜色列表。简而言之,当用户通过下拉列表更改难度级别时,应生成一组新的颜色并进行显示。我认为这是一个非常简单的练习,但是事情并未按预期进行。每当我改变难度时,它都不会做出反应(重新呈现ColorsGrid
组件),只有在我再次选择另一个(困难)级别之后,上一个才会引发重新呈现。例如,如果要在初始渲染后选择“中”(默认级别设置为“简单”),则没有任何变化。但是,如果我回到“轻松”(或选择其他任何难度),那么是否会发生与前一个(中等难度)相对应的更改,即ColorsGrid重新渲染,因此显示了与中等难度相对应的网格。我在做什么错了?
下面是相关代码。
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
// Get random rgb color
function randomColor() {
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
return `rgb(${r}, ${g}, ${b})`;
}
// Set length of color list array as a funciton of difficulty
function colorsListLength(difficulty) {
switch (true) {
case difficulty === 'expert':
return 25;
case difficulty === 'hard':
return 20;
case difficulty === 'medium':
return 10;
default:
return 5;
}
}
// Get color list array
function colorsList(colorsLength = 5) {
const colors = [];
while (colors.length < colorsLength) {
colors.push(randomColor());
}
return colors;
}
// Set random color to guess from (above) color list array
function randomColorToGuess(colors) {
const index = Math.floor(Math.random() * colors.length);
return colors[index];
}
// Set number of game tries as a function of difficulty
function numberOfTries(difficulty) {
switch (true) {
case difficulty === 'expert' || difficulty == 'hard':
return 2;
case difficulty === 'medium':
return 1;
default:
return 0;
}
}
// Colors grid component
function ColorsGrid({ difficulty, colorsList }) {
return (
<div>
<strong>Colors Grid</strong>
<p>Difficulty: {difficulty}</p>
<div>
{colorsList.length > 0 ? (
colorsList.map(color => (
<div
style={{
backgroundColor: color,
height: '3rem',
width: '3rem',
borderRadius: '50%',
}}
key={color}
/>
))
) : (
<div>Loading colors...</div>
)}
</div>
</div>
);
}
// Main component
class App extends Component {
constructor(props) {
super(props);
this.state = {
difficulty: 'easy',
colorsList: [],
};
this.colorsArray = this.colorsArray.bind(this);
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
this.colorsArray(this.state.difficulty);
}
colorsArray() {
const colors = colorsList(colorsListLength(this.state.difficulty));
const colorToGuess = randomColorToGuess(colors);
this.setState(() => ({
colorsList: colors,
gameTries: numberOfTries(this.state.difficulty),
colorToGuess,
}));
}
handleChange(e) {
this.setState({
difficulty: e.target.value,
});
this.colorsArray(this.state.difficulty); // I was under the impression the (difficulty) state had already been updated here
}
render() {
return (
<div className="App">
<h1>Colors</h1>
<div style={{ textAlign: 'right' }}>
<select
id="difficulty"
value={this.state.difficulty}
onChange={this.handleChange}
>
<option value="easy">Easy</option>
<option value="medium">Medium</option>
<option value="hard">Hard</option>
<option value="expert">Expert</option>
</select>
</div>
<ColorsGrid
colorsList={this.state.colorsList}
difficulty={this.state.difficulty}
/>
</div>
);
}
}
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
答案 0 :(得分:3)
这是因为setState()
是异步:
setState(newState,回调);
为了获得刚刚选择的难度,您必须像这样更改代码:
this.setState({
difficulty: e.target.value,
}, () => this.colorsArray(this.state.difficulty)
);
答案 1 :(得分:-1)
问题在于您对setState的调用是否协调。以下是解决问题的方法:
colorsArray(difficulty) {
const colors = colorsList(colorsListLength(difficulty));
const colorToGuess = randomColorToGuess(colors);
this.setState(() => ({
difficulty,
colorsList: colors,
gameTries: numberOfTries(this.state.difficulty),
colorToGuess
}));
}
handleChange(e) {
this.colorsArray(e.target.value);
}
您可以看到事件处理程序对颜色更新功能进行了一次调用。然后计算出新的颜色并将状态设置在一个位置。