Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React应用程序未按预期对更改做出响应。为什么?_Javascript_Reactjs - Fatal编程技术网

Javascript React应用程序未按预期对更改做出响应。为什么?

Javascript React应用程序未按预期对更改做出响应。为什么?,javascript,reactjs,Javascript,Reactjs,伙计们。我有一个可能是noob的问题,但我还是会开枪的。下面的代码片段相当简单,我不应该有问题,但我们开始吧。我正在尝试将ColorsGrid组件中的颜色列表设置为。简而言之,当用户通过下拉列表更改难度级别时,应该生成并显示一组新的颜色。我认为这是一个非常简单的练习,但事情并没有如预期的那样进行。每当我改变难度时,它都不会做出反应(重新渲染ColorsGrid组件),只有在我再次选择另一个(难度)级别后,上一个级别才会引发重新渲染。例如,如果在初始渲染后选择“介质”(默认级别设置为“轻松”),则

伙计们。我有一个可能是noob的问题,但我还是会开枪的。下面的代码片段相当简单,我不应该有问题,但我们开始吧。我正在尝试将
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
切换(难度)
的自然方式是
切换(难度)
案例
案例“中等”
案例“困难”
等等!这很有效。我有这个的另一个版本,但出了点问题,因此,它抛出了一个错误。谢谢