Ниже у меня есть серия кода React, в котором на странице отображается несколько кружков, каждый из которых имеет разный цвет. При нажатии на цвет отображается nav, который меняется в зависимости от выбранного цвета.
import { useState } from "react";
const Color = ({ color, setSelectedColor}) => {
return <div className = {color} onClick = {() => setSelectedColor(color)}></div>;
};
const App = () => {
const [selectedColor, setSelectedColor] = useState("");
return (
<div id = "container">
<div id = "navbar">
<div>Currently selected: </div>
<div className = {selectedColor}>{selectedColor}</div>
</div>
<div id = "colors-list">
<Color color = "violet" setSelectedColor = {setSelectedColor}/>
<Color color = "orange" setSelectedColor = {setSelectedColor}/>
<Color color = "yellow" setSelectedColor = {setSelectedColor}/>
</div>
</div>
);
};
export default App;
В CSS есть class, который я назвал selected, который просто создает рамку вокруг круга. Проблема, с которой я столкнулся, заключается в том, как именно применить class к selectedColor? Я имею в виду тернарные операторы, но я новичок в React, поэтому не знаю, как мне это реализовать.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вам нужно добавить переменную, чтобы проверить, соответствует ли опора color реквизиту selectedColor, и если они совпадают, вы добавляете класс selected, а с помощью тернарного оператора вы можете применять как классы color, так и selected.
import { useState } from "react";
const Color = ({ color, setSelectedColor, selectedColor }) => {
const isSelected = color === selectedColor ? "selected" : "";
return (
<div
className = {`${color} ${isSelected}`} // Apply both color and selected classes
onClick = {() => setSelectedColor(color)}
></div>
);
};
const App = () => {
const [selectedColor, setSelectedColor] = useState("");
return (
<div id = "container">
<div id = "navbar">
<div>Currently selected: </div>
<div className = {selectedColor}>{selectedColor}</div>
</div>
<div id = "colors-list">
<Color color = "violet" selectedColor = {selectedColor} setSelectedColor = {setSelectedColor} />
<Color color = "orange" selectedColor = {selectedColor} setSelectedColor = {setSelectedColor} />
<Color color = "yellow" selectedColor = {selectedColor} setSelectedColor = {setSelectedColor} />
</div>
</div>
);
};
export default App;
Вы можете улучшить компонент «Цвет», добавив атрибут «isSelected». Этот атрибут будет указывать, соответствует ли текущий цвет выбранному цвету. Следовательно, на основе значения атрибута isSelected вы можете динамически применять класс «selected» рядом с классом «color» в компоненте «Цвет».
вот модифицированный код:
import { useState } from "react";
const Color = ({ color, isSelected, setSelectedColor}) => {
return <div className = {`${color} ${isSelected ? 'selected' : ''}`} onClick = {() => setSelectedColor(color)}></div>;
};
const App = () => {
const [selectedColor, setSelectedColor] = useState("");
return (
<div id = "container">
<div id = "navbar">
<div>Currently selected: </div>
<div className = {selectedColor}>{selectedColor}</div>
</div>
<div id = "colors-list">
<Color color = "violet" isSelected = {selectedColor === 'violet'} setSelectedColor = {setSelectedColor} />
<Color color = "orange" isSelected = {selectedColor === 'orange'} setSelectedColor = {setSelectedColor}/>
<Color color = "yellow" isSelected = {selectedColor === 'yellow'} setSelectedColor = {setSelectedColor}/>
</div>
</div>
);
};
export default App;
Вы можете применить класс к selectedColor, передав selectedColor в качестве реквизита компоненту Color и дополнительно проверив, соответствует ли selectedColorcolor, т.е.:
const selected = selectedColor === color ? "selected" : "";
Ниже приведен рефакторинг кода.
Цвета были извлечены в состояние Colors, и обратите внимание на использование .map для рендеринга элементов состояния. Это поможет уменьшить избыточность и сохранить код чистым.
Я также добавил немного стилей для визуализации.
NB: Вы заметите, что {color} также был добавлен в div в компоненте Color, это сделано для того, чтобы вы могли видеть что-то по умолчанию.
import { useState } from "react";
import "./App.css";
const Color = ({ color, selectedColor, setSelectedColor }) => {
const selected = selectedColor === color ? "selected" : "";
return (
<div
className = {`${color} ${selected}`}
onClick = {() => setSelectedColor(color)}
>
{color}
</div>
);
};
const App = () => {
const colors = ["violet", "orange", "yellow"];
const [selectedColor, setSelectedColor] = useState("");
return (
<div id = "container">
<div id = "navbar">
<div>Currently selected: </div>
<div className = {selectedColor}>{selectedColor}</div>
</div>
<div id = "colors-list">
{colors.map((color, index) => (
<Color
key = {index}
color = {color}
selectedColor = {selectedColor}
setSelectedColor = {setSelectedColor}
/>
))}
</div>
</div>
);
};
export default App;
CSS
.yellow,
.orange,
.violet {
width: 80px;
height: 80px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
cursor: pointer;
}
.selected.yellow {
border: 2px solid yellow;
}
.selected.orange {
border: 2px solid orange;
}
.selected.violet {
border: 2px solid violet;
}
К какому элементу вы пытаетесь применить этот класс?
<div>, который отображает выбранный цвет, или сами выбираемые цветовые элементы? Все, что находится внутри фигурных скобок{}для атрибута/свойства любого элемента/компонента, является просто выражением JavaScript, как и любое другое, независимо от React. Если вы хотите добавить несколько классов, это выражение просто должно привести к строке, содержащей эти классы.