So I have created a group of three buttons where you can select the size of the pizza, the problem is that all three buttons are the same so when I click one, all of them activate. How can I make so that only the button that is clicked is activated?
Code:
/** @jsxImportSource @emotion/react */
import React, { useState } from 'react';
import styles from './PizzaSize.styles';
export const PizzaSize: React.FC = () => {
const [selected, setSelected] = useState<boolean>(false);
const clickHandler = () => {
setSelected(!selected);
};
return (
<div css={styles.pizza__size__selector}>
<button
id="1"
css={
selected
? [styles.pizza__size__btn, styles.pizza__size__btn__selected]
: styles.pizza__size__btn
}
onClick={clickHandler}
>
S
</button>
<button
id="2"
css={
selected
? [styles.pizza__size__btn, styles.pizza__size__btn__selected]
: styles.pizza__size__btn
}
onClick={clickHandler}
>
M
</button>
<button
id="3"
css={
selected
? [styles.pizza__size__btn, styles.pizza__size__btn__selected]
: styles.pizza__size__btn
}
onClick={clickHandler}
>
L
</button>
</div>
);
};
CodePudding user response:
You could save the string ('S', 'M', 'L') instead of a boolean, and then in each css prop, check if selected
equals the corresponing letter.
Like in the following example
import React, { useState } from 'react';
import styles from './PizzaSize.styles';
export const PizzaSize: React.FC = () => {
const [selected, setSelected] = useState<string>('');
// Set or reset the selected size
const setSelectedSize = (size: string) => {
if (!selected) setSelected(size);
else setSelected(''); // Reset if click on active button
}
return (
<div css={styles.pizza__size__selector}>
<button
id="1"
css={
selected === 'S'
? [styles.pizza__size__btn, styles.pizza__size__btn__selected]
: styles.pizza__size__btn
}
onClick={() => setSelectedSize('S')}
>
S
</button>
<button
id="2"
css={
selected === 'M'
? [styles.pizza__size__btn, styles.pizza__size__btn__selected]
: styles.pizza__size__btn
}
onClick={() => setSelectedSize('M')}
>
M
</button>
<button
id="3"
css={
selected === 'L'
? [styles.pizza__size__btn, styles.pizza__size__btn__selected]
: styles.pizza__size__btn
}
onClick={() => setSelectedSize('L')}
>
L
</button>
</div>
);
};
CodePudding user response:
I optimized your code, when your code is repeating you have to generalize it, you can make a separate component or you can do as you see in the code below, you need to use a unique key (index) to show Button active, as I use the index and pass the index to the clickHandler
function. I hope this would be helpful. Thanks
/** @jsxImportSource @emotion/react */
import React, { useState } from 'react';
import styles from './PizzaSize.styles';
export const PizzaSize: React.FC = () => {
const [selected, setSelected] = useState(null);
const clickHandler = (index) => {
setSelected(index);
};
const data = [
{
id: "1",
name: "S"
},
{
id: "2",
name: "M"
},
{
id: "3",
name: "L"
},
]
return (
<div css={styles.pizza__size__selector}>
{data.map((item, index) => (
<button
id={item.id}
css={
selected === index
? [styles.pizza__size__btn, styles.pizza__size__btn__selected]
: styles.pizza__size__btn
}
onClick={() => clickHandler(index)}
>
{item.name}
</button>
))}
</div>
);
};