I am trying to change the class of a button in react js on click using hooks. The problem is when the class toggle happens through a state change, the result of the class toggle is seen but the page re-renders, rendering the initial class (not the one that is toggled to). Please help
Buttons
<button className={buttonColor1?styles.priceButtonWhite:styles.priceButtonGreen} onClick={() => changeColor(1)}>100</button>
<button className={buttonColor2?styles.priceButtonWhite:styles.priceButtonGreen} onClick={() => changeColor(2)}>200</button>
<button className={buttonColor3?styles.priceButtonWhite:styles.priceButtonGreen} onClick={() => changeColor(3)}>300</button>
Change Color Function
const changeColor = (n) => {
if (n==1){
setButtonColor1(!buttonColor1);
}
else if (n==2){
setButtonColor2(!buttonColor2);
}
else{
setButtonColor3(!buttonColor3 );
}
}
Hooks
const [buttonColor1, setButtonColor1] = useState(true);
const [buttonColor2, setButtonColor2] = useState(true);
const [buttonColor3, setButtonColor3] = useState(true);
SCSS
.priceButton{
border-radius: 10px;
padding: 10px;
border: none;
}
.priceButtonWhite{
@extend .priceButton;
background: white;
border: 1px solid #166C6C;
}
.priceButtonGreen{
@extend .priceButton;
background: #166C6C;
}
On button click, the class gets toggled to priceButtonGreen, then the entire page re-renders leaving the class priceButtonWhite on the buttons
CodePudding user response:
I created a working example here: https://codesandbox.io/s/suspicious-curie-90t4c?file=/src/App.js
Since the style object is missing in your example It's hard to see what is the mistake in your code.
function Toggler() {
const [buttonColor1, setButtonColor1] = useState(true);
const [buttonColor2, setButtonColor2] = useState(true);
const [buttonColor3, setButtonColor3] = useState(true);
return (
<div>
<button
className={`priceButton ${
buttonColor1 ? "priceButtonWhite" : "priceButtonGreen"
}`}
onClick={() => setButtonColor1(!buttonColor1)}
>
100
</button>
<button
className={`priceButton ${
buttonColor2 ? "priceButtonWhite" : "priceButtonGreen"
}`}
onClick={() => setButtonColor2(!buttonColor2)}
>
200
</button>
<button
className={`priceButton ${
buttonColor3 ? "priceButtonWhite" : "priceButtonGreen"
}`}
onClick={() => setButtonColor3(!buttonColor3)}
>
300
</button>
</div>
);
}
.priceButton {
border-radius: 10px;
padding: 10px;
border: none;
}
.priceButtonWhite {
background: white;
border: 1px solid #166c6c;
}
.priceButtonGreen {
background: #166c6c;
}
Within the structure you proposed this is a working solution.
CodePudding user response:
When you have button
element inside form
element then clicking on a button will cause the page to reload (button
element has type
attribute set to submit
by default).
You can either change the type
of a button to button
or use event.preventDefault()
in the button listener.