3

I have 2 React components Memory and children MemoryShape

At the Memory component i have method newGame which setting 4 random MemoryShapes to the purple color when i clicking on button, but when i clicked all shapes got purple color not 4 that i wants

import React, { Component } from 'react';
import './memory.css';
import MemoryShape from './MemoryShape';
import randomShape from './helpers/help';

class Memory extends Component {
  constructor(props) {
    super(props);
    this.state = {
      memoryshapes: new Array(16).fill(Math.random() * 1321132),


    };

    this.preInitGame = this.preInitGame.bind(this);

    this.newGame = () => {
      const [...shapes] = this.state.memoryshapes;
      const coloredShapesIndexes = randomShape(4, 15);
      coloredShapesIndexes.forEach((value) => {
        shapes[value].shape.style.backgroundColor = 'purple';
      });

      console.log(shapes);
      this.setState({ memoryshapes: shapes });
    };
  }

  componentWillMount() {
    this.preInitGame();
  }


  preInitGame() {
    let [...memoryshapes] = this.state.memoryshapes;
    const data = {
      shape: {
        style: {
          setColor(nextColor) {
            this.backgroundColor = nextColor;
          },
          backgroundColor: 'green',
        },
      },
    };
    memoryshapes = memoryshapes.map((value) => {
      let newValue = value;
      newValue = data;

      return newValue;
    });

    this.setState({ memoryshapes });
  }


  render() {
    const shapes = this.state.memoryshapes.map((value, index) => {
      const arrkey = index + value;
      return (<MemoryShape
        key={arrkey}
        tabIndex={index}
        backgroundColor={value.shape.style.backgroundColor}
      />);
    });
    return (
      <div>
        {shapes}
        <br />
        <button
          style={{
            padding: 20,
            marginLeft: 300,
          }}
          onClick={this.newGame}
        >
          Start Game
        </button>
        <MemoryShape
          tabIndex={-124}
          backgroundColor="blue"
        />
      </div>
    );
  }
}

export default Memory;

class MemoryShape extends Component {
  constructor(props) {
    super(props);
    this.state = { backgroundColor: 'green' };

    this.changeColor = () => {

    };
    this.handleKeyDown = () => {

    };
  }
  componentWillReceiveProps(nextProps) {
    console.log(nextProps.backgroundColor);
    this.setState({ backgroundColor: nextProps.backgroundColor });
  }


  render() {
    return (
      <div
        className="memory-shape"
        onKeyDown={this.handleKeyDown}
        onClick={this.changeColor}
        role="button"
        tabIndex={this.props.tabIndex}
        backgroundColor={this.props.backgroundColor}
        style={{ backgroundColor: this.state.backgroundColor }}
      />
    );
  }
}

MemoryShape.propTypes = {
  backgroundColor: PropTypes.string,
  tabIndex: PropTypes.number.isRequired,
};
MemoryShape.defaultProps = {
  backgroundColor: 'transparent',
};

export default MemoryShape;

1
  • Do you want to update your shapes object based on click? Commented Nov 29, 2017 at 16:02

2 Answers 2

2

Make sure you have unique property in array of objects! Just added id property and everything works!

Sign up to request clarification or add additional context in comments.

1 Comment

Congrats for your own try!
2

To set color for 4 random components first we need to get 4 random indexes of object on click. Based on your need I have done simple example to randomly set background color of component based on onClick. Here is the working jsfiddle. And working code is below,

<!DOCTYPE html>
<html>
  <head>
    <title>React Color Change</title>
    <meta charset="utf-8">
    <script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script type="text/jsx">
        class App extends React.Component {
          constructor(props){
            super(props)
            this.state = {
                shapes: [
                    {shape: "shape1", backgroundColor: "purple"}, 
                    {shape: "shape2", backgroundColor: "purple"}, 
                    {shape: "shape3", backgroundColor: "purple"},
                    {shape: "shape4", backgroundColor: "purple"}, 
                    {shape: "shape5", backgroundColor: "purple"}, 
                    {shape: "shape6", backgroundColor: "purple"},
                    {shape: "shape7", backgroundColor: "purple"}, 
                    {shape: "shape8", backgroundColor: "purple"}, 
                    {shape: "shape9", backgroundColor: "purple"},
                    {shape: "shape10", backgroundColor: "purple"}, 
                    {shape: "shape11", backgroundColor: "purple"}, 
                    {shape: "shape12", backgroundColor: "purple"},
                    {shape: "shape13", backgroundColor: "purple"}, 
                    {shape: "shape14", backgroundColor: "purple"}, 
                    {shape: "shape15", backgroundColor: "purple"},
                ]
            }
          }

          changeColor() {
            const shapes = this.state.shapes;

            shapes.map((data, i) => { // Reset already selected
                if(data.backgroundColor == "green")
                    data.backgroundColor = "purple";
            })

            // Generate 4 random indexes
            let rand_array = [];
            while(rand_array.length < 4){
                var randomnumber = Math.floor(Math.random()*(shapes.length - 1)) + 1;
                if(rand_array.indexOf(randomnumber) > -1) continue;
                rand_array[rand_array.length] = randomnumber;
            }

            //Update shape by generated indexes
            rand_array.map((data) => shapes[data].backgroundColor = "green");

            this.setState({shapes});
          }

          render(){
            return (
                <div>
                    {this.state.shapes.map((data, index) => {
                        return (
                            <Shapes data={data} changeColor={() => this.changeColor()}/>
                        )
                    })}
                </div>
            )
          }
        }

        const Shapes = (props) => {
            return (
                <div style={{backgroundColor: `${props.data.backgroundColor}`, padding: '5px', margin: "1%", width: "50%"}} 
                onClick={props.changeColor}>
                    {props.data.shape}
                </div>
            )
        }

        ReactDOM.render(
          <App/>, 
          document.getElementById("app")
        );
    </script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

Hope this will helps you!

1 Comment

yes, how to set color of 1 component with onclick i know! but i am trying to set 4 random components colors from 16 components and problem is all components gets new colors not 4 random components which i expected

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.