简体   繁体   中英

React js random color

I am using random colors in my component https://ibb.co/PwLSMYH , everything works fine, Every time the page is refreshed, my colors change, everything is fine but I have the same colors for each block, and I want for each block to have different colors (here is an example picture https://ibb.co/jbz50nt )

import React from 'react';
import "./Achievements.css";

import crown from "./icons/online-course.png"
import goal from "./icons/goal.png"
import money from "./icons/money.png"
import target from "./icons/target.png"
import clipboard from "./icons/clipboard.png"
import climbing from "./icons/climbing.png"

export class AchievementsBeta extends React.Component {
    constructor() {
        super();
        this.state = {
            CoursesPage: [
                {
                    img: crown,
                    cardInfo: "Engaged in!",
                    cardLabel: "Complete the lesson",
                    cardColorStyle: 'card__fire',
                },

                {
                    img: goal,
                    cardInfo: "The first path to victory",
                    cardLabel: "complete five courses",
                    cardColorStyle: 'card__fire',
                },

                {
                    img: money,
                    cardInfo: "Piggy bank",
                    cardLabel: "Earn 100 XP",
                    cardColorStyle: 'card__fire',
                },

                {
                    img: target,
                    cardInfo: "Sniper",
                    cardLabel: "Complete the course without errors",
                    cardColorStyle: 'card__fire',
                },

                {
                    img: clipboard,
                    cardInfo: "Dear Citizen",
                    cardLabel: "Fill in all credentials",
                    cardColorStyle: 'card__fire',
                },

                {
                    img: climbing,
                    cardInfo: "My first avatar",
                    cardLabel: "Set avatar",
                    cardColorStyle: 'card__fire',
                },
            ],

            bgColor: [
                '#1ec891',
                '#ff725e',
                '#ffd05b',
            ],

            selectedColor: '',
        }
    }

    componentDidMount() {
        this._getRandomColor()
    }

    _getRandomColor(){
        const item = this.state.bgColor[Math.floor(Math.random()*this.state.bgColor.length)];
        this.setState({
            selectedColor: item,
        })
    }

    render() {

        const resultsRender = this.state.CoursesPage.map((user, index) => {
            return (

                <div style={{ width: "100%", marginBottom: "35px" }} key={index}>
                    <div style={{borderLeft: `5px solid ${this.state.selectedColor} `}} className={`${"Beta"} ${"card__fire"}`}>
                        <div className={"imgContainer"}>
                            <img src={user.img} alt="" />
                        </div>

                        <div>
                            <div className="cardInfo">
                                <p>{user.cardInfo}</p>
                            </div>

                            <div className="cardDescription">
                                <p>{user.cardLabel}</p>
                            </div>
                        </div>
                    </div>
                </div>

            );
        }

        );

        return (
            <div>
                {resultsRender}
            </div>
        );
    }
}

You have to move the function which is getting random color inside the children components.

Currently, there is no child component and you just randomize once in the parent component when it mounts and then map-render the cards using that one randomized color state.

So, my suggestion is to create a child component which has it's own randomize color function when it got mounted and separated the states of color.

Then, use that child component to map-render and show your card with their own color state.

TL:DR; Move selectedColor single state of parent into children's own state of color.

Please refer to my codesandbox: https://codesandbox.io/s/color-randomizer-evogk?file=/src/ColorCard.js

Try to change your _getRandomColor function to get just random color and don't change the state. That function will then be a pure function.

Then you can add a blockColor key to the each element of the CoursesPage array in the state:

this.state = {
  CoursesPage: [
    {
      img: crown,
      cardInfo: "Engaged in!",
      cardLabel: "Complete the lesson",
      cardColorStyle: 'card__fire',
      blockColor: this._getRandomColor(),
    },
    ...
  ],   
}        

And use it when you renders blocks:

const resultsRender = this.state.CoursesPage.map((user, index) => {
  return (
    <div style={{ width: "100%", marginBottom: "35px" }} key={index}>
      <div
        style={{ borderLeft: `5px solid ${user.blockColor} ` }}
        className={`${"Beta"} ${"card__fire"}`}
      >
        <div className={"imgContainer"}>
          <img src={user.img} alt="" />
        </div>

        <div>
          <div className="cardInfo">
            <p>{user.cardInfo}</p>
          </div>

          <div className="cardDescription">
            <p>{user.cardLabel}</p>
          </div>
        </div>
      </div>
    </div>
  );
});

You can change the change CoursesPage before you render each item in the render method by calling the reduce method on it to change the structure of each object and attach to it a random color

 class App extends React.Component { constructor(props) { super(props); this.state = { CoursesPage: [ { img: "crown", cardInfo: "Engaged in,": cardLabel, "Complete the lesson": cardColorStyle, 'card__fire', }: { img, "goal": cardInfo, "The first path to victory": cardLabel, "complete five courses": cardColorStyle, 'card__fire', }: { img, "money": cardInfo, "Piggy bank": cardLabel, "Earn 100 XP": cardColorStyle, 'card__fire', }: { img, "target": cardInfo, "Sniper": cardLabel, "Complete the course without errors": cardColorStyle, 'card__fire', }: { img, "clipboard": cardInfo, "Dear Citizen": cardLabel, "Fill in all credentials": cardColorStyle, 'card__fire', }: { img, "climbing": cardInfo, "My first avatar": cardLabel, "Set avatar": cardColorStyle, 'card__fire', }, ]: bgColor, [ '#1ec891', '#ff725e', '#ffd05b', ]. } } render() { let courses = [...this.state.CoursesPage].map((course) => { return {..,course: bgColor. this.state.bgColor[Math.floor(Math.random() * this.state.bgColor.length)] } }) return <ul> {courses,map((c: idx) => { return (<li key={idx} style={{ backgroundColor. `${c.bgColor}` }}> {c;cardInfo} </li>). })} </ul> } } ReactDOM,render(<App />. document;querySelector('#root'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM