【问题标题】:How to use useState hook for a randomizing array problem(React useState)?如何使用 useState 钩子解决随机数组问题(React useState)?
【发布时间】:2021-04-04 09:42:09
【问题描述】:

我试图弄清楚如何解决一个应用 useState 钩子概念的颜色框练习。给定一个包含 12 种不同颜色的数组,最初状态将显示 12 个具有相应颜色的 div。单击按钮后,只有随机选择的 div 会更改为随机颜色(在 12 种给定颜色中),并在 div 上使用“已更改”消息标记该 div。到目前为止,我能够使颜色框容器在 div 上显示每种颜色。每次单击时,我都会看到状态变为随机颜色。但我不知道如何只制作随机 div 来更改颜色并显示消息。这个问题是否需要每个颜色的唯一 id 来跟踪状态的变化?

import React, { useState } from 'react';
import ColorBox from './ColorBox';
import {choice} from './colorHelpers';


const ColorBoxes = () => {
   
    const [ boxes, setBoxes] = useState(colors);
    
    const [msg, setMsg] = useState(null);
        
    const clickHandler = () => {
        setBoxes(()=>choice(colors));
        setMsg('changed');    
    };
        

    return (
    <>  
        {colors.map((color,i) =>{
            return(
            <div>
               <ColorBox key={i} color={color} />{color} 
            </div>
            );
        })} 
        <button onClick={clickHandler}>Change Color!</button>    
    </>
    );

};

import React from 'react';
import './ColorBox.css';

const ColorBox = ({ color }) => {
    return <div className="colorBox" style={{ backgroundColor: color }} />;
};

export default ColorBox;


const choice = (arr) => {
    const randIdx = Math.floor(Math.random() * arr.length);
    return arr[randIdx];
};

export { choice };

【问题讨论】:

    标签: reactjs use-state


    【解决方案1】:

    您应该将初始颜色保存在 useState 中,然后使用 useState 更改随机索引的颜色,查看此示例:

    const colors = [
      "#8391B5",
      "#290D11",
      "#0C9ABC",
      "#0E17F4",
      "#97BC89",
      "#6B48F7",
      "#584A35",
      "#669F15",
      "#15FC93",
      "#7C8329",
      "#27D792",
      "#4786C8",
    ];
    
    const ColorBoxes = () => {
      const [boxes, setBoxes] = React.useState(
        colors.sort(() => Math.random() - 0.5)
      );
      const [msg, setMsg] = React.useState(Array.from(Array(12)));
    
      const clickHandler = (index) => {
        const randomColor = colors[Math.floor(Math.random() * 12)];
        setBoxes((prev) => prev.map((x, i) => (i === index ? randomColor : x)));
        setMsg((prev) => prev.map((x, i) => (i === index ? "changed!" : x)));
      };
    
      return (
        <React.Fragment>
          {boxes.map((color, i) => (
            <ColorBox key={i + color} color={color} msg={msg[i]} />
          ))}
          <button onClick={() => clickHandler(Math.floor(Math.random() * 12))}>
            Change Color!
          </button>
        </React.Fragment>
      );
    }
    const ColorBox = ({ color, msg }) => (
      <div className="colorBox" style={{ backgroundColor: color }}>
        {color} {msg}
      </div>
    );
    
    ReactDOM.render(
      <ColorBoxes />,
      document.getElementById("react")
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <div id="react"></div>

    【讨论】:

    • 非常感谢您的示例代码。它也对我有用。您认为我可以使用诸如 setbox([...box], randomColor) 之类的扩展运算符来代替 map 吗?
    • 欢迎您,是的,您可以,如果您将初始状态(数组)更改为对象,实际上我认为这会更好,您可以将 2 个useState 数组合并为 1 个对象。
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 2020-04-29
    • 2021-05-25
    • 2020-11-02
    • 2021-02-07
    • 1970-01-01
    相关资源
    最近更新 更多