const [toggleValue, setToggleValue] = useState();
..
..
{Items.map((item) => (
<Card onClick={() => setToggleValue(item.id)} key={item.id}>
<CardHeader text={item.text} />
<Collapse isOpen={toggleValue=== item.id}>
<CardBody>
<FormGroup>
<CustomInput value="1" type="radio" id="yes" onChange={handleOptionChange(item.id, '1')} />
<CustomInput value="2" type="radio" id="yes" onChange={handleOptionChange(item.id, '2')} />
</FormGroup>
</CardBody>
</Collapse>
</Card>
It works as intended, but when I use the radio button to choose an option in any of these cards, it automatically collapses the current card and expands the first card. The handleOptionChange function which is triggered on making a radio button selection also changes a different value in the state using useState:
const handleOptionChange = (name, value) => () => {
const Item = name;
const numericValue = Number(value);
setFormData({
...data,
id: Item,
vote: numericValue,
});
};
handleOptionChange(item.id, '1') should not be directly called on onChange
const [toggleValue, setToggleValue] = useState();
..
..
{Items.map((item) => (
<Card onClick={() => setToggleValue(item.id)} key={item.id}>
<CardHeader text={item.text} />
<Collapse isOpen={toggleValue=== item.id}>
<CardBody>
<FormGroup>
<CustomInput value="1" type="radio" id="yes" onChange={()=>handleOptionChange(item.id, '1')} />
<CustomInput value="2" type="radio" id="yes" onChange={()=>handleOptionChange(item.id, '2')} />
</FormGroup>
</CardBody>
</Collapse>
</Card>
change this
<CustomInput value="1" type="radio" id="yes" onChange={handleOptionChange(item.id, '1')} />
into this
<CustomInput value="1" type="radio" id="yes" onChange={() => handleOptionChange(item.id, '1')} />
Reason for the cause ,properly
For the onChange={() => ....} without () =>is same is you will run the function when component mount without waiting for any user action.
You can test by alerting
onChange={() => alert('will run only when user change')}
...
onChange={alert('Will not wait for user and run when component mount')}
JavaScript event will bubble up to the nearest parent that have a event listener for the event
So in this case when you click on the radio button, it actually trigger an onClick event which bubble up to the onClick event listener of your Card component, thus calling the onClick setToggleValue function
You can add a onClick={(event)=>event.stopPropagation()} to your CustomIInput component to prevent this behavior