TLDR- I want to change the backgroundColor of 1 square onClick. I am not sure how to differentiate this 1 square from the other 63 since they are created dynamically
I am dynamically creating a Board composed of 64 squares and I want a square's background color to change if selected under the proper conditions (preferably under the selectPiece function) and then revert back after a move is made or the piece on the square is unselected. My problem is identifying the dynamically created square to change its state.
Board.js
let [squareStyle] = useState('squares ');
function Row(i){
const newRow = [];
let count = i * 8;
let squareImp;
for (let j = 0; j<8; j++){
if ((i + j) % 2 === 1){
squareImp = squareStyle + "g";
}else {
squareImp = squareStyle + "y";
}
newRow.push(<div key={count} id={i * 10 + j} className={squareImp} onClick={isMove ? selectMove : props.data[count].name !== null ? selectPiece : undefined }>
{ (props.data[count].name != null) &&
<img src={images[props.data[count].name]}
className="icons"
alt="chess piece" />
}
</div>)
count++;
}
return <div className="rows" key={i}>{newRow}</div>;
}
If I was using class based Components, then I could use this.setState to change the individual square, using something like -
this.setState({className: "squares b"})
but with Function Components, the setState is unique to each property. So while I can use the id (currently not used for CSS) to grab the selected square, I can't create a [state, setState] variable for each square. Is it possible to dynamically create a variable? aka something like
function setBackground(int id){
let StateChange = id + ""
setStateChange({backgroundColor:"blue"})
It doesn't seem to be.
So after I have spent quite a bit of time reading the multitudes of posts on here about how to dynamically change the CSS in React I tried following the only article that I thought might apply to me here- How to add a CSS class to an element on click - React and set the className with a function like so -
Board.js
function Row(i){
const newRow = [];
let count = i * 8;
for (let j = 0; j<8; j++){
newRow.push(<div key={count} id={i * 10 + j} className={getClassName(i, j)} onClick={isMove ? selectMove : props.data[count].name !== null ? selectPiece : undefined }>
{ (props.data[count].name != null) &&
<img src={images[props.data[count].name]}
className="icons"
alt="chess piece" />
}
</div>)
count++;
}
return <div className="rows" key={i}>{newRow}</div>;
}
//function getClassName(e, i, j){ //can't read e
function getClassName(i, j){
console.log(i, j)
//console.log(e.currentTarget)
let base = "squares ";
if (clicked){
// if (clicked && e.currentTarget.id == i * 10 + j){ //this is what I want but I can't figure out how to grab the target to compared the id to
return base + "b";
} else {
if ((i + j) % 2 === 1){
return base + "g";
}else {
return base + "y";
}
}
}
but as you can probably tell from the commented out text, I can't figure out how to grab the event and thus use the id to compare so that I am only changing the background color of the selected square rather than the whole board.
I don't understand the nuances of event handling but I am guessing that because I am calling the function from within the className attribute of the div element rather than from the element itself, that the event just isn't available. I am not sure how to get around it.
Any help would be appreciated