Javascript React应用程序未按预期对更改做出响应。为什么?
伙计们。我有一个可能是noob的问题,但我还是会开枪的。下面的代码片段相当简单,我不应该有问题,但我们开始吧。我正在尝试将Javascript React应用程序未按预期对更改做出响应。为什么?,javascript,reactjs,Javascript,Reactjs,伙计们。我有一个可能是noob的问题,但我还是会开枪的。下面的代码片段相当简单,我不应该有问题,但我们开始吧。我正在尝试将ColorsGrid组件中的颜色列表设置为。简而言之,当用户通过下拉列表更改难度级别时,应该生成并显示一组新的颜色。我认为这是一个非常简单的练习,但事情并没有如预期的那样进行。每当我改变难度时,它都不会做出反应(重新渲染ColorsGrid组件),只有在我再次选择另一个(难度)级别后,上一个级别才会引发重新渲染。例如,如果在初始渲染后选择“介质”(默认级别设置为“轻松”),则
ColorsGrid
组件中的颜色列表设置为。简而言之,当用户通过下拉列表更改难度级别时,应该生成并显示一组新的颜色。我认为这是一个非常简单的练习,但事情并没有如预期的那样进行。每当我改变难度时,它都不会做出反应(重新渲染ColorsGrid
组件),只有在我再次选择另一个(难度)级别后,上一个级别才会引发重新渲染。例如,如果在初始渲染后选择“介质”(默认级别设置为“轻松”),则不会发生任何更改。但是,如果我返回到Easy(或选择任何其他难度),那么是否会发生与上一个(中等难度)对应的更改,即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);
import React,{Component}来自'React';
从“react dom”导入react dom;
//获取随机rgb颜色
函数randomColor(){
设r=Math.floor(Math.random()*256);
设g=Math.floor(Math.random()*256);
设b=Math.floor(Math.random()*256);
返回`rgb(${r},${g},${b})`;
}
//将颜色列表数组的长度设置为难度函数
函数颜色长度(难度){
开关(真){
案例难度==“专家”:
返回25;
案例难度==‘困难’:
返回20;
案例难度==“中等”:
返回10;
违约:
返回5;
}
}
//获取颜色列表数组
函数颜色列表(颜色长度=5){
常量颜色=[];
while(colors.length颜色网格
难度:{难度}
{colorsList.length>0(
colorsList.map(颜色=>(
))
) : (
正在加载颜色。。。
)}
);
}
//主要成分
类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
难度:“容易”,
颜色列表:[],
};
this.colorsArray=this.colorsArray.bind(this);
this.handleChange=this.handleChange.bind(this);
}
componentDidMount(){
this.colorsArray(this.state.diffusion);
}
色光{
const colors=colorsList(colorsListLength(this.state.coverity));
const colorToGuess=随机颜色(颜色);
此.setState(()=>({
颜色列表:颜色,
游戏次数:游戏次数(这个。状态。难度),
色彩,
}));
}
手变(e){
这是我的国家({
难度:即目标值,
});
this.colorsArray(this.state.defestion);//我觉得这里的(难度)状态已经更新了
}
render(){
返回(
颜色
容易的
中等
硬的
专家
);
}
}
const rootElement=document.getElementById('root');
render(,rootElement);
这是因为setState()
是异步的:
设置状态(newState,callback)
为了获得刚刚选择的难度,您必须更改如下代码:
this.setState({
difficulty: e.target.value,
}, () => this.colorsArray(this.state.difficulty)
);
问题是如何协调对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);
}
您可以看到,事件处理程序只调用了一次颜色更新函数。然后计算出新的颜色并在一个位置设置状态。使用回调函数
setState
,并在回调函数内部而不是This.state
,使用state
参数setState
是异步操作,因此This.state.难度在This.colorsArray()时可以设置,也可以不设置
被称为旁白,在colorsListLength
中的开关(true)
在我看来像是一种代码气味。为什么不打开<代码>切换<代码>难度<代码>呢?我只是不明白为什么你的案例都是案例难度===xxx
的切换(难度)
的自然方式是切换(难度)
案例案例“中等”
,案例“困难”
等等!这很有效。我有这个的另一个版本,但出了点问题,因此,它抛出了一个错误。谢谢