当您使用changeActivityStyleBasedOnZone函数单击区域按钮时,我正在尝试更改活动按钮的颜色。例如,如果我点击一个区域按钮;"浓度";如果活动按钮具有类型",我想将它们的颜色更改为相同的颜色;浓度";。现在,当您单击区域按钮时,所有活动按钮都会更改颜色。现在我有一个功能,如果你点击一个活动按钮,它会根据活动的类型而改变颜色,这是我想要保留的。如何在不影响其他活动按钮的情况下,仅使与单击的区域按钮类型相同的按钮更改颜色?我还尝试过对类型上的活动数组进行过滤,然后通过过滤后的数组进行映射,以仅在过滤后的阵列上设置状态,但可能这是错误的方法,或者我做得不对,因为映射似乎不起作用。
import React, { useState } from 'react';
const Game = (activityType) => {
const [activityStyle, setActivityStyle] = useState("activity");
const [zoneClicked, setZoneClicked] = useState(false);
const [clickedActivityIndex, setClickedActivityIndex] = useState(-1);
const zones = [
{id: 1, name: "Concentration", styleType: "concentration-zone", type: "concentration" },
{id: 2, name: "Communication", styleType: "communication-zone", type: "communication"},
{id: 3, name: "Collaboration", styleType: "collaboration-zone", type: "collaboration"},
{id: 4, name: "Chill Out", styleType: "chill-out-zone", type: "chillout"},
{id: 5, name: "Camp", styleType: "camp-zone", type: "camp"}
]
const activities = [
{id: 1, name: "Code", type: "concentration"},
{id: 2, name: "Teams Meeting", type: "communication"},
{id: 3, name: "Make a phone call", type: "camp"},
{id: 4, name: "Work shops with colleagues", type: "collaboration"},
{id: 5, name: "Coffee break", type: "chillout"},
{id: 6, name: "Lively discussions & brainstorming", type: "collaboration"},
]
const changeActivityStyle = (activityType, index) => {
setClickedActivityIndex(index);
if (activityType === "concentration") {
setActivityStyle("activity-concentration");
setClickedActivityIndex(0) ;
}
if (activityType === "communication") {
setActivityStyle("activity-communication");
}
if (activityType === "camp") {
setActivityStyle("activity-camp");
}
if (activityType === "chillout") {
setActivityStyle("activity-chill-out");
}
if (activityType === "collaboration") {
setActivityStyle("activity");
}
return;
};
const changeActivityStyleBasedOnZone = (zoneType) => {
setZoneClicked(true);
if (zoneType === "concentration") {
const concentrationActivities = activities.filter(activity => activity.type === "concentration");
concentrationActivities.map((ca) => {
setActivityStyle("activity-concentration");
});
}
if (zoneType === "communication") {
setActivityStyle("activity-communication");
}
if (zoneType === "camp") {
setActivityStyle("activity-camp");
}
if (zoneType === "chillout") {
setActivityStyle("activity-chill-out");
}
if (zoneType === "collaboration") {
setActivityStyle("activity");
}
return;
}
return (
<>
<section className="header"><h2>Click on an activity box to see which area it belongs to</h2></section>
<section className="game-area">
<div className="activity-zone-container">
<div className="zone-container">
{zones.map((zone =>
<button
className="zone"
id={zone.styleType}
key={zone.id}
zoneType={zone.type}
onClick={() => changeActivityStyleBasedOnZone(zone.type,
activityType)}
>
<p>{zone.name}</p>
</button>
))}
</div>
<div className="activity-container">
{activities.map((activity, index) =>
<button
className={clickedActivityIndex === index | zoneClicked === true ? activityStyle: 'activity'}
onClick={() => changeActivityStyle(activity.type, index)}
key={activity.id}
activityType={activity.type}>
<p>{activity.name}</p>
</button>
)}
</div>
</div>
</section>
</>
);
};
CSS
#concentration-zone {
background-color: orange;
}
#communication-zone {
background-color: yellow;
}
#communication-zone p {
color: black;
}
#collaboration-zone {
background-color: #3260a8;
}
#chill-out-zone {
background-color: pink;
}
#chill-out-zone p {
color: black;
}
#camp-zone {
background-color: green;
}
.activity {
background-color: #3260a8;
margin: 17px;
display: flex;
justify-content: center;
cursor: pointer;
width: 140px;
height: 87px;
}
.activity-concentration {
background-color: orange;
margin: 17px;
display: flex;
justify-content: center;
color: white;
width: 140px;
height: 87px;
}
.activity-communication {
background-color: yellow;
margin: 17px;
display: flex;
justify-content: center;
width: 140px;
height: 87px;
}
.activity-chill-out {
background-color: pink;
margin: 17px;
display: flex;
justify-content: center;
width: 140px;
height: 87px;
}
.activity-camp {
background-color: green;
margin: 17px;
display: flex;
justify-content: center;
color: white;
width: 140px;
height: 87px;
}
这里有很多问题。我将尝试以合理的顺序处理它们,然后在最后提供示例代码。
问题
1。由于以下行,所有按钮都在变色:
className={clickedActivityIndex === index | zoneClicked === true ? activityStyle: 'activity'}
如果zoneClicked
是true
,则存储在activityStyle
中的类将应用于所有按钮。同时,一旦调用changeActivityStyleBasedOnZone
,zoneClicked
就被设置为true
:
const changeActivityStyleBasedOnZone = (zoneType) => {
setZoneClicked(true);
...
}
2。changeActivityStyle
和changeActivityStyleBasedOnZone
相互冲突。
它们都会更改activityStyle
,因此当前值将应用于具有匹配条件的按钮,并覆盖以前的类值。这在逻辑上很混乱,不清楚changeActivityStyle
的意义所在。我的假设是,您希望将不同的样式应用于所选活动,而与所选区域样式无关。
3。changeActivityStyle
和changeActivityStyleBasedOnZone
中的if
块是不必要的,并且使代码复杂化。
这个特定的区块是有问题的。它多次将相同的值应用于activityStyle
。我把它从我的解决方案中完全删除了,但我想让你知道这一点。
if (zoneType === "concentration") {
const concentrationActivities = activities.filter(
(activity) => activity.type === "concentration"
);
concentrationActivities.map((ca) => {
setActivityStyle("activity-concentration");
});
}
4.zoneType
和activityType
不是有效的htmlbutton
属性。
使用data-
属性创建自定义属性。名称必须全部为小写字母。例如data-activity-type
和data-zone-type
解决方案
正如我所说,我不完全确定你的目标,而且我没有你的CSS,所以你需要根据你的用例调整它。也就是说,我认为这会让你接近。
下面是一个带有完整示例的CodeSandbox。我添加了一个表来显示状态值。
首先,我将changeActivityStyle
和changeActivityStyleBasedOnZone
更改为:
const changeActivityStyle = (index) => {
setClickedActivityIndex(index);
};
const changeActivityStyleBasedOnZone = (zone) => {
setZoneClicked(zone);
return;
};
您会注意到这意味着zoneClicked
现在存储整个zone
对象。因此,将useState
挂钩更改为:
const [zoneClicked, setZoneClicked] = useState({});
区域按钮onClick
变为:
onClick={() => changeActivityStyleBasedOnZone(zone)}
然后我更改了活动按钮className
,如下所示:
<button
className={
`${activity.type === zoneClicked.type ? zoneClicked.styleType :"activity"}
${clickedActivityIndex === index ? "selected" : ""}`
}
onClick={(e) => changeActivityStyle(index)}
key={activity.id}
data-activity-type={activity.type}
>
使用模板文字,我们可以基于两个条件应用两个不同的类,一个与所选区域相关,另一个与选定活动相关。
由于zoneClicked
现在存储整个区域,所以我只应用所选区域的styleType
作为类名。
如果选定的活动索引匹配,我将应用一个附加类来突出显示选定的按钮。在这种情况下,类只是删除了边框,但您可以应用任何您想要的样式。请注意selected
类中的!important
运算符,这样可以确保区域类在以后应用时不会覆盖它。
尝试这个链接,告诉我应用程序是否应该这样工作。https://growingillfatedrate.pskath1.repl.co/
这是的工作代码
import React,{ useState } from 'react';
const activities = [
{id: 1, name: "Code", type: "concentration"},
{id: 2, name: "Teams Meeting", type: "communication"},
{id: 3, name: "Make a phone call", type: "camp"},
{id: 4, name: "Work shops with colleagues", type: "collaboration"},
{id: 5, name: "Coffee break", type: "chill-out"},
{id: 6, name: "Lively discussions & brainstorming", type: "collaboration"},
];
const zones = [
{id: 1, name: "Concentration", styleType: "concentration-zone", type: "concentration" },
{id: 2, name: "Communication", styleType: "communication-zone", type: "communication"},
{id: 3, name: "Collaboration", styleType: "collaboration-zone", type: "collaboration"},
{id: 4, name: "Chill Out", styleType: "chill-out-zone", type: "chill-out"},
{id: 5, name: "Camp", styleType: "camp-zone", type: "camp"}
];
const Game = () => {
const [activityStyle, setActivityStyle] = useState("activity");
const [zoneClicked, setZoneClicked] = useState(false);
const [clickedActivityIndex, setClickedActivityIndex] = useState(-1);
const changeActivityStyle = (activityType, index) => {
setClickedActivityIndex(index);
if (activityType === "concentration") {
setActivityStyle("concentration");
setClickedActivityIndex(0) ;
}
if (activityType === "communication") {
setActivityStyle("communication");
}
if (activityType === "camp") {
setActivityStyle("camp");
}
if (activityType === "chillout") {
setActivityStyle("chill-out");
}
if (activityType === "collaboration") {
setActivityStyle("collaboration");
}
if (activityType === "chill-out") {
setActivityStyle("chill-out");
}
return;
};
const changeActivityStyleBasedOnZone = (zoneType) => {
setZoneClicked(true);
if (zoneType === "concentration") {
setActivityStyle("concentration")
}
if (zoneType === "communication") {
setActivityStyle("communication");
}
if (zoneType === "camp") {
setActivityStyle("camp");
}
if (zoneType === "chill-out") {
setActivityStyle("chill-out");
}
if (zoneType === "collaboration") {
setActivityStyle("collaboration");
}
return;
}
return (
<>
<section className="header"><h2>Click on an activity box to see which area it belongs to</h2></section>
<section className="game-area">
<div className="activity-zone-container">
<div className="zone-container">
{zones.map((zone =>
<button
className={zone.type}
id={zone.styleType}
key={zone.id}
zoneType={zone.type}
onClick={() => changeActivityStyleBasedOnZone(zone.type)}
>
<p>{zone.name}</p>
</button>
))}
</div>
<div className="activity-container">
{activities.map((activity, index) =>
<button
className={activityStyle == activity.type ? activityStyle: '' }
onClick={() => { changeActivityStyle(activity.type, index) }}
key={activity.id}
activityType={activity.type}>
<p>{activity.name}</p>
</button>
)}
</div>
</div>
</section>
</>
);
};
还有相同的repl链接,你可以添加你的风格并在路上进行测试。https://replit.com/@pskath1/成长命运多舛日期?v=1