Reputation: 42
I have multiple 'Rectangle' components in a 'Wall' that should change color when clicked. The onClick in 'Rectangle' is used in another Component that will make the 'Rectangle' hidden or not. I tried to do something similar here, but I can't change variables inside the 'Rectangle' component.
My attempt
customClickEvent={() =>{this.props.color = hidden_dictionary[count];}}
Wall.js
const [count, setCount] = useState(0);
const color_dictionary = {0: "bg-red-400", 1: "bg-blue-400", 2:"bg-green-400", 3:"bg-yellow-400"};
return (
<div className="grid grid-flow-col grid-rows-4 lg:py-20 gap-y-1 gap-x-1 lg:gap-y-6 lg:gap-x-6 justify-center items-center">
<Rectangle type="wall">Fiji</Rectangle>
<Rectangle type="wall">Hazelnut</Rectangle>
<Rectangle type="wall">Mocha</Rectangle>
<Rectangle type="wall">Australia</Rectangle>
<Rectangle type="wall">Cook Islands</Rectangle>
<Rectangle type="wall">Cube</Rectangle>
<Rectangle type="wall">Vanilla</Rectangle>
<Rectangle type="wall">Butter Pecan</Rectangle>
<Rectangle type="wall">San Pellegrino</Rectangle>
<Rectangle type="wall">Coconut</Rectangle>
<Rectangle type="wall">Papua New Guinea</Rectangle>
<Rectangle type="wall">Caramel</Rectangle>
<Rectangle type="wall">Prince</Rectangle>
<Rectangle type="wall">Guam</Rectangle>
<Rectangle type="wall">Champagne</Rectangle>
<Rectangle type="wall">T</Rectangle>
</div>
)
Rectangle.js
//ANSWER
if(props.type === "answer") {
width = "p-2";
height = "h-12 lg:h-20";
text_size = "text-2xl sm:text-4xl lg:text-5xl";
}
//WALL
else if (props.type === "wall")
{
width = "w-20 sm:w-24 lg:w-52 cursor-pointer";
height = "h-16 sm:h-20 lg:h-40";
text_size = "text-1xl lg:text-4xl";
color = props.color;
}
//VOWELS
else if (props.type === "vowels")
{
width = "p-4";
height = "";
text_size = "text-3xl sm:text-4xl lg:text-5xl";
color = "bg-blue-800 text-white";
}
else
{
width = "w-16 sm:w-36 lg:w-80";
height = "h-12 sm:h-28 lg:h-64";
text_size = "text-2xl sm:text-6xl lg:text-8xl";
}
return (
<div onClick={props.customClickEvent} className={width + " " + height + " " + props.color + " " + " shadow-2xl rounded-md " + props.hidden}>
<h1 className={text_size + " w-full h-full flex justify-center items-center text-center"}>{props.children}</h1>
</div>)
Upvotes: 0
Views: 224
Reputation: 2618
Props aren’t designed to be mutable. In other words, setting a new value on this.props.color
won’t cause the rectangle to re-render. Even if it did, the value of this
in your callback will be for the instance of Wall
, because you’re using an arrow function, which inherits its this
from the surrounding scope.
One solution would be to have your Wall component store the colour of each Rectangle as state, and pass that via the color
prop. Your callback handler could then change the colour. However, because you have multiple Rectangles
, you would need some way of distinguishing between them an index or perhaps ID.
If it’s not important for your Wall
to know whether the Rectangle
has been clicked, then it would be simpler to define the click handler inside Rectangle
and have it modify state in the Rectangle
, i.e:
const [color, setColor] = useState();
return (
<div onClick={() => setColor(‘new colour’)} className={width + " " + height + " " + color + " " + " shadow-2xl rounded-md " + props.hidden}>
<h1 className={text_size + " w-full h-full flex justify-center items-center text-center"}>{props.children}</h1>
</div>)
Upvotes: 3
Reputation: 1727
Have You tried toggling the CSS class onClick ? That class would be styled according to Your needs. The only thing You have to do it do dynamically add a class.
Upvotes: 0