Reputation: 137
I have some buttons and I'm trying to add active
class for clicked button. But when I click one of the buttons, all buttons are getting active class.
const { useState } = React;
const { render } = ReactDOM;
const node = document.getElementById("root");
const Button = ({ message }) => {
const [condition, setCondition] = useState(false);
return (
<div>
{
Object.keys(res).map((data) => (
<Button className={condition ? "button toggled" : "button"} onClick=.
{() => {
setCondition(!condition)}
}}
))
}
</div>
);
//Updated
Object.keys(res).map((data) => (
<Button className={condition ? "button toggled" : "button"} onClick=.
{() => {
setCondition(condition === "off" ? "on" : "off")}
}}
))
}
</div>
); //This can be modified to work for button clicked. Because active class is added to all buttons, if one of them is clicked
};
render(<Button message="Click me if you dare!" />, node);
This is working if I click the first button, but if I click again the same button, this active class should be removed
Upvotes: 1
Views: 7970
Reputation: 400
import React, {useState, useCallback} from "react";
const defaultButtons = [
{id: 1},
{id: 2},
{id: 3},
{id: 4}
];
export default function App() {
const [toggledButtonId, setToggledButtonId] = useState(false);
function toggleButton(button) {
setToggledButtonId(button.id);
}
const toggleButton = useCallback((id) => setToggledButtonId(state => id), [toggledButtonId]);
return (
<div>
{defaultButtons.map(button => {
const isToggled = button.id === toggledButtonId;
return (
<button
key={button.id}
className={isToggled ? "toggledButtonId toggled" : "toggledButtonId"}
onClick={toggleButton(button.id)}>
{String(isToggled)}
</button>
)
})}
</div>
)
}
Upvotes: 0
Reputation: 355
You could create component Button with state within and use this component to populate buttons. Probably you can use :active CSS selector and avoid js at all
Upvotes: 0
Reputation: 658
maybe you want to check this.
https://codesandbox.io/embed/import-css-file-react-vs488?fontsize=14&hidenavigation=1&theme=dark
Upvotes: 0
Reputation: 3138
Here is a very naive solution, but it will help you understand the problem.
If you're on a real project, I suggest you to use an existing library (that can be found by searching react toggle button group
)
import React, {useState} from "react";
const defaultButtons = [
{id: 1},
{id: 2},
{id: 3},
{id: 4}
];
export default function App() {
const [toggledButtonId, setToggledButtonId] = useState(null);
function toggleButton(button) {
setToggledButtonId(button.id);
}
return (
<div>
{defaultButtons.map(button => {
const isToggled = button.id === toggledButtonId;
return (
<button
key={button.id}
className={isToggled ? "toggledButtonId toggled" : "toggledButtonId"}
onClick={() => toggleButton(button)}>
{String(isToggled)}
</button>
)
})}
</div>
)
}
Upvotes: 2
Reputation: 341
You need to use a seperate state handler for each button:
const Button = ({ message }) => {
const [condition, setCondition] = useState(false);
const [condition2, setCondition2] = useState(false);
return (
<div>
<div
onClick={() => setCondition(!condition)}
className={condition ? "button toggled" : "button"}
>
{message}
</div>
<div
onClick={() => setCondition(!condition2)}
className={condition2 ? "button toggled" : "button"}
>
{message}
</div>
</div>
);
};
render(<Button message="Click me if you dare!" />, node);
Upvotes: 0