TLDR-我想更改 1 个正方形 onClick 的背景颜色。我不知道如何区分这 1 个方 block 和其他 63 个方 block ,因为它们是动态创建的
我正在动态创建一个由 64 个方 block 组成的棋盘,并且如果在适当的条件下(最好是在 selectPiece 函数下)选择方 block ,我希望方 block 的背景颜色能够改变,然后在进行移动或方 block 上的棋子后恢复回来未选中。我的问题是识别动态创建的方 block 以更改其状态。
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 来更改单个方 block ,使用类似 -
this.setState({className: "squares b"})
但是对于函数组件,setState 对于每个属性都是唯一的。因此,虽然我可以使用 id(当前未用于 CSS)来获取选定的方 block ,但我无法为每个方 block 创建一个 [state, setState] 变量。是否可以动态创建变量?又名类似
function setBackground(int id){
let StateChange = id + ""
setStateChange({backgroundColor:"blue"})
好像不是。
因此,在我花了相当多的时间阅读这里有关如何在 React 中动态更改 CSS 的大量帖子之后,我尝试遵循我认为可能适用于我的唯一一篇文章 - How to add a CSS class to an element on click - 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 进行比较,这样我只更改所选方 block 的背景颜色而不是整个方 block 的背景颜色板。
我不明白事件处理的细微差别,但我猜测因为我是从 div 元素的 className 属性而不是元素本身调用该函数,所以该事件不可用。我不知道如何解决它。
如有任何帮助,我们将不胜感激
最佳答案
所以我会这样做。我将 Square 抽象为它自己的组件,它是通过 for 循环创建的。每个 Square 都可以管理自己的本地状态,因此当单击它们时,它们可以更新自己的状态,并且您不需要困惑的集中式代码。
仅供引用,您似乎错误地使用了useState
,因为它确实有自己的函数来更新其本地状态。下面的代码不是 100% 正确,因为我不确定你在做什么,但它应该给你一个大概的轮廓。
我还会查看 React 文档:https://reactjs.org/docs/hooks-state.html
这样您就可以清楚地了解 useState
Hook 及其使用方式。
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";
}
}
}
关于javascript - 如何动态更改 react 中动态片段的样式(使用功能组件)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64648645/