如何在react中动态更改动态片段的样式(使用功能组件)



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";
}
}
}

最新更新