TLDR-我想在Click上更改1个正方形的背景颜色。我不知道如何将这1个正方形与其他63个区分开来,因为它们是动态创建的
我正在动态创建一个由64个正方形组成的板,如果在适当的条件下(最好是在selectPiece功能下(选择,我希望正方形的背景颜色发生变化,然后在移动或取消选择正方形上的块后返回。我的问题是识别动态创建的正方形以更改其状态。
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>;
}
如果我使用的是基于类的组件,那么我可以使用this.setState来更改单个正方形,使用类似于-的东西
this.setState({className: "squares b"})
但是对于Function Components,setState对于每个属性都是唯一的。因此,虽然我可以使用id(目前不用于CSS(来获取所选的正方形,但我不能为每个正方形创建[state,setState]变量。是否可以动态创建一个变量?也就是类似的东西
function setBackground(int id){
let StateChange = id + ""
setStateChange({backgroundColor:"blue"})
似乎不是。
因此,在我花了相当多的时间阅读了这里关于如何在React中动态更改CSS的大量帖子后,我试着阅读了我认为可能适用于我的唯一一篇文章-如何在点击时将CSS类添加到元素中-React并用类似这样的函数设置className-
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";
}
}
}
但正如你可能从评论出来的文本中看到的那样,我不知道如何抓住事件,从而使用id进行比较,所以我只改变所选正方形的背景色,而不是整个棋盘。
我不理解事件处理的细微差别,但我猜测,因为我是从div元素的className属性中调用函数,而不是从元素本身调用函数,所以事件不可用。我不知道如何避开它。
如有任何帮助,将不胜感激
所以我会这样做。我将Square抽象为它自己的组件,它是通过for循环创建的。这些Square中的每一个都可以管理自己的本地状态,因此当点击它们时,它们可以更新自己的状态,而不需要有混乱的集中代码。
仅供参考,您似乎错误地使用了useState
,因为它确实有自己的功能来更新其本地状态。下面的代码不是100%正确的,因为我不确定你在做什么,但它应该给你一个大致的轮廓。
我还将审查React文档:https://reactjs.org/docs/hooks-state.html
这样您就可以清楚地了解useState
挂钩以及如何使用它。
const { useState } from 'react'
const Square = (i, j, data, count, isMove, selectMove) => {
const [ squareStyle, setSquareStyle ] = useState('square') // then use setSquareStyle('STYLING) to update local state
const selectedPiece = data[count].name
return (
<div key={count}
id={i * 10 + j}
className={getClassName(i, j)}
onClick={isMove ? selectMove : selectedPiece ? selectPiece : undefined }>
{ (selectedPiece.name != null) &&
<img src={images[props.data[count].name]}
className="icons"
alt="chess piece" />
}
</div>
)
}
function Row(i){
const newRow = [];
let count = i * 8;
for (let j = 0; j<8; j++){
newRow.push(
<Square
i={i}
j={j}
count={count}
isMove={isMove}
selectMove={selectMove}
/>
)
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";
}
}
}