【问题标题】:random button is not working as expected (React)随机按钮未按预期工作(反应)
【发布时间】:2022-01-21 09:00:48
【问题描述】:

好的,所以我正在处理我的第一个反应项目,并且我面临着我创建的随机按钮的问题。

enter image description here

导航栏上的随机按钮应该生成数字并将其插入输入的值,然后块根据值改变它的颜色。 发生的情况是它在第一次单击时生成输入值,然后在第二次单击时更改块颜色和输入。 所以发生的情况是输入与下一次点击的颜色相匹配。

export const ColorsProvider = (props) => {
  const [color, setColor] = useState("");
  const [red, setRed] = useState("");
  const [green, setGreen] = useState("");
  const [blue, setBlue] = useState("");
  const [colors, setColors] = useState([]);

  const changeColor = () => {
    if (
      red < 0 ||
      red > 255 ||
      green < 0 ||
      green > 255 ||
      blue < 0 ||
      blue > 255 ||
      !red ||
      !green ||
      !blue
    ) {
      console.log("Input must be between 0 and 255");
    } else {
      setColor(`rgb(${red}, ${green}, ${blue})`);
      setColors([...colors, color]);
    }
  };

  return (
    <ColorsContext.Provider
      value={{
        colorValue: [color, setColor],
        redValue: [red, setRed],
        greenValue: [green, setGreen],
        blueValue: [blue, setBlue],
        colorsArr: [colors, setColors],
        clickHandler: changeColor,
      }}
    >
      {props.children}
    </ColorsContext.Provider>
  );
};

function Navbar() {
  const {
    colorValue,
    redValue,
    greenValue,
    blueValue,
    colorsArr,
    clickHandler,
  } = useContext(ColorsContext);
  const [color, setColor] = colorValue;
  const [red, setRed] = redValue;
  const [green, setGreen] = greenValue;
  const [blue, setBlue] = blueValue;
  const [colors, setColors] = colorsArr;
  const changeColor = clickHandler;

  const generateNewColorOnClick = () => {
    service.ColorsService.getRandomColor().then((color) => {
      setColor(color.color);
      let colorArray = color.color.split(",");
      setRed(colorArray[0]);
      setGreen(colorArray[1]);
      setBlue(colorArray[2]);
      changeColor();
    });
  };

  return (
    <section>
      <div className="navbar-dark">
        <div>
          <a href="javascript:window.location.reload(true)">
            <h1>Color Generator</h1>
          </a>
        </div>

        <div>
          <a className={"href"} onClick={generateNewColorOnClick}>
            <h2>Random</h2>
          </a>
        </div>
      </div>
    </section>
  );
}

function ChooseColor() {
  const {
    colorValue,
    redValue,
    greenValue,
    blueValue,
    colorsArr,
    clickHandler,
  } = useContext(ColorsContext);
  const [color, setColor] = colorValue;
  const [red, setRed] = redValue;
  const [green, setGreen] = greenValue;
  const [blue, setBlue] = blueValue;
  const [colors, setColors] = colorsArr;
  const changeColor = clickHandler;

  return (
    <div className={"home"}>
      <section>
        <div className="container">
          <div>
            <p>Choose a color</p>
          </div>
          <div className="container-box" style={{ backgroundColor: color }} />
          <div>
            <div>
              RGB <h3>between 0-255</h3>
            </div>
            <div className={"input"}>
              <input
                type="number"
                placeholder="Red"
                name="Red"
                value={red}
                max="255"
                id="redValue"
                onChange={(e) => setRed(e.target.value)}
              />
              <input
                type="number"
                placeholder="Green"
                name="Green"
                value={green}
                max="255"
                id="greenValue"
                onChange={(e) => setGreen(e.target.value)}
              />
              <input
                type="number"
                placeholder="Blue"
                name="Blue"
                value={blue}
                max="255"
                id="blueValue"
                onChange={(e) => setBlue(e.target.value)}
              />
            </div>
          </div>
          <button className={"homeButton"} onClick={changeColor}>
            Click to Generate
          </button>
        </div>
        <History colors={colors} />
      </section>
    </div>
  );
}

【问题讨论】:

    标签: javascript reactjs random


    【解决方案1】:

    未经测试,但从我在ColorsProvider 中看到的情况来看,您正在尝试设置color 状态并使用您认为更新后的color 状态来更新colors 状态。 React 状态更新是异步处理的,所以在 changeColor 回调中 color 仍然是渲染外壳的当前状态值。

    const changeColor = () => {
      if (
        red < 0 ||
        red > 255 ||
        green < 0 ||
        green > 255 ||
        blue < 0 ||
        blue > 255 ||
        !red ||
        !green ||
        !blue
      ) {
        console.log("Input must be between 0 and 255");
      } else {
        setColor(`rgb(${red}, ${green}, ${blue})`);
        setColors([...colors, color]); // <-- color is current state
      }
    };
    

    您可以:

    1. 传递刚刚用于setColor的相同颜色值:

      const changeColor = () => {
        if (
          ....
        ) {
          console.log("Input must be between 0 and 255");
        } else {
          const newColor = `rgb(${red}, ${green}, ${blue})`;
          setColor(newColor);
          setColors(colors => [...colors, newColor]);
        }
      };
      
    2. 使用useEffect 挂钩更新colors 状态以响应color 状态更新。

      const changeColor = () => {
        if (
          ....
        ) {
          console.log("Input must be between 0 and 255");
        } else {
          setColor(`rgb(${red}, ${green}, ${blue})`);
        }
      };
      
      useEffect(() => {
        setColors(colors => [...colors, color]);
      }, [color]);
      

    【讨论】:

    • 好的,首先感谢您的帮助!我很感激。所以当我点击“点击生成”按钮时,使用 newColor 的第一种方法使我的代码工作得更好。但随机按钮仍然像以前一样工作。我认为它与 useState 颜色初始化有关。
    • @YardenYosef 很有趣。认为您可以为您的代码创建一个正在运行的 代码和框,以重现我们可以现场检查和调试的问题?我也不太明白随机按钮的问题是什么,你能澄清一下吗?
    猜你喜欢
    • 2020-10-31
    • 2021-02-03
    • 1970-01-01
    • 2010-12-30
    • 2018-10-16
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多