Для каждой кнопки нужно индивидуальное состояние. Я предлагаю использовать карту для хранения идентификатора кнопки и логического значения того, является она «черным» или нет, то есть обработчик кликов просто переключает логическое значение. Я не знаю, была ли это опечатка при копировании / вставке кода в SO, но состояние реакции необходимо объявить в в теле функционального компонента.
const [isBlack, setIsBlack] = useState({});
Вы также можете использовать обработчик одиночного щелчка, преобразовав его в каррированный обратный вызов, взяв и заключив в область видимости идентификатор кнопки. При этом используется обновление функционального состояния для поверхностного копирования существующего состояния и обновления значения идентификатора заключенной кнопки.
const handleBtn = btnId => e => {
e.preventDefault();
setIsBlack(state => ({
...state,
[btnId]: !state[btnId],
}));
};
Полный код
function Mata() {
const [activeTab, setActiveTab] = useState("activeTab");
const [isBlack, setIsBlack] = useState({});
const handleBtn = btnId => e => {
e.preventDefault();
setIsBlack(state => ({
...state,
[btnId]: !state[btnId]
}));
};
return (
<div className="container">
<button
style={{ backgroundColor: isBlack["btn1"] ? "#262626" : "#F3F3F3" }}
className={`btn1 ${isBlack["btn1"] && activeTab}`}
onClick={handleBtn("btn1")}
>
btn1
</button>
<button
style={{ backgroundColor: isBlack["btn2"] ? "#262626" : "#F3F3F3" }}
className={`btn2 ${isBlack["btn2"] && activeTab}`}
onClick={handleBtn("btn2")}
>
btn2
</button>
<button
style={{ backgroundColor: isBlack["btn3"] ? "#262626" : "#F3F3F3" }}
className={`btn3 ${isBlack["btn3"] && activeTab}`}
onClick={handleBtn("btn3")}
>
btn3
</button>
<button
style={{ backgroundColor: isBlack["btn4"] ? "#262626" : "#F3F3F3" }}
className={`btn4 ${isBlack["btn4"] && activeTab}`}
onClick={handleBtn("btn4")}
>
btn4
</button>
<button
style={{ backgroundColor: isBlack["btn5"] ? "#262626" : "#F3F3F3" }}
className={`btn5 ${isBlack["btn5"] && activeTab}`}
onClick={handleBtn("btn5")}
>
btn5
</button>
</div>
);
}
Существует много повторяющегося кода, поэтому более DRY версия, где активная вкладка и кнопки передаются как реквизиты.
function Mata({ activeTab = '', buttons }) {
const [isBlack, setIsBlack] = useState({});
const handleBtn = btnId => e => {
e.preventDefault();
setIsBlack(state => ({
...state,
[btnId]: !state[btnId]
}));
};
return (
<div className="container">
{buttons.map(btn => (
<button
style={{ backgroundColor: isBlack[btn] ? "#262626" : "#F3F3F3" }}
className={`btn1 ${isBlack[btn] && activeTab}`}
onClick={handleBtn(btn)}
>
{btn}
</button>
))}
</div>
);
}
Используется как таковое
const buttons = ["btn1", "btn2", "btn3", "btn4", "btn5"];
...
<Mata buttons={buttons} />
Edit
Seems you are really creating a "tab manager". I suggest lofting state to the parent and converting Mata
to a "dumb" component that simply renders the "tab" buttons. Takes 3 props: an active tab index, array of buttons, and a state update callback.
function Mata({ activeTab = -1, buttons, setActiveTab }) {
return (
{buttons.map ((btn , i) => {const isActive = i === activeTab; return ( setActiveTab (i)}> {btn.id} );})} ); }
Пример данных вкладок
const tabs = [
{ id: "btn1", data: "data1" },
{ id: "btn2", data: "data2" },
{ id: "btn3", data: "data3" },
{ id: "btn4", data: "data4" },
{ id: "btn5", data: "data5" }
];
Пример использования
<Mata activeTab={activeTab} buttons={tabs} setActiveTab={setActiveTab} />
{activeTab === -1 ? (
<div>Social Media</div>
) : (
<div>{tabs[activeTab].data}</div>
)}
Adding "Icons"
Similar to Выбор типа во время выполнения
Если значки SVG еще не являются реагирующими компонентами, оберните их в простой функциональный компонент
const Icon1 = () => <svg>...</svg>;
Добавьте поле значка к данным вкладок и установите значение для компонента значка
const tabs = [
{ id: "btn1", data: "data1", icon: Icon1 },
{ id: "btn2", data: "data2", icon: Icon2 },
{ id: "btn3", data: "data3", icon: Icon3 },
{ id: "btn4", data: "data4", icon: Icon4 },
{ id: "btn5", data: "data5", icon: Icon5 }
];
И деструктурируйте и переименуйте, чтобы отобразить
function Mata({ activeTab = -1, buttons, setActiveTab }) {
return (
<div className="container">
{buttons.map((btn, i) => {
const isActive = i === activeTab;
const { icon: Icon, id } = btn; // <-- rename icon -> Icon
return (
<button
key={id}
style={{ backgroundColor: isActive ? "#262626" : "#F3F3F3" }}
className={`${id} ${isActive && activeTab}`}
onClick={() => setActiveTab(i)}
>
<Icon /> {id} // <-- render icon component
</button>
);
})}
</div>
);
}