Reputation: 422
function EachData({ data, index, open }) {
const [isOpen, setisOpen] = useState(open);
const toggle = (e) => {
setisOpen((prev) => !prev);
};
return (
<tr>
{/*<td></td>'s ... */}
<td>
<div className="functions">
{!isOpen ? (
<>
<label className="far fa-edit" htmlFor={`label-${index + 1}`}>
<input type="radio" name="edit" id={`label-${index + 1}`} onChange={toggle} />
</label>
<label className="far fa-trash"></label>
</>
) : (
<>
<label className="far fa-circle-check"></label>
<label className="far fa-times-circle" htmlFor={`label-${index + 1}`} >
<input type="radio" name="edit" id={`label-${index + 1}`} onChange={toggle} />
</label>
</>
)}
</div>
</td>
</tr>
);
}
export default EachData;
App.js
array.map((data, index)=>{
return(
<EachData data={data} index={index} isOpen={false}/>
)
})
When I check the radio buttons the jsx changes as expected, but after checking another radio button the previous one's state remains true. How do I set those elements state to false ?
Upvotes: 1
Views: 791
Reputation: 1479
You should use useRef
instead of id, here I make some logic with useRef
I hope this would be helpful.
As per my understand, when you click on radio button in map
function this will be activated and when you click another radio button previous radio button is still showing active, In this code I create two useRef
as you see the below code, one is taking for all indexes
and second for removing previous radio button active. I hope you understand this code, if you know DOM.
function EachData({ data, index, open }) {
const [isOpen, setisOpen] = useState(open);
const radioRef = useRef([]);
const previousRadioRef = useRef([]);
const toggle = (i) => {
setisOpen((prev) => !prev);
if (previousRadioRef.current && previousRadioRef.current[0] !== radioRef.current[i]) {
if (radioRef.current[i]) {
if (previousRadioRef.current.length) {
previousRadioRef.current[0].checked = false;
previousRadioRef.current = [];
}
radioRef.current[i].checked = true;
previousRadioRef.current.push(radioRef.current[i]);
}
} else if(previousRadioRef.current && previousRadioRef.current[0]) {
previousRadioRef.current[0].checked = false;
previousRadioRef.current = [];
}
};
return (
<>
<tr>
<td>
<div className="functions">
{!isOpen ? (
<>
<label className="far fa-edit">
<input type="radio" name="edit" ref={ref => (radioRef.current[index] = ref)} onChange={() => toggle(index)} />
</label>
<label className="far fa-trash"></label>
</>
) : (
<>
<label className="far fa-circle-check"></label>
<label className="far fa-times-circle">
<input type="radio" name="edit" ref={ref => (radioRef.current[index] = ref)} onChange={() => toggle(index)} />
</label>
</>
)}
</div>
</td>
</tr>
</>
);
}
export default EachData;
array.map((data, index)=>{
return(
<EachData data={data} index={index} open={false}/>
)
})
Upvotes: 1
Reputation: 829
You can set state with the name of radio input. Reference: http://react.tips/radio-buttons-in-reactjs/
Upvotes: 0
Reputation: 5529
You should store isOpen
state in your array
data, not in EachData
component
const [array, setArray] = useState();
const toggle = idx => {
const newArray = array.map((item, index) => {
if (idx == index) return {
...item,
isOpen: !item.isOpen
}
return item
})
setArray(newArray);
}
array.map((data, index) => {
return <EachData data={data} index={index} isOpen={data.isOpen} toggle={toggle} />;
});
function EachData({ data, index, isOpen, toggle }) {
return (
<tr>
{/*<td></td>'s ... */}
<td>
<div className="functions">
{!isOpen ? (
<>
<label className="far fa-edit" htmlFor={`label-${index + 1}`}>
<input
type="radio"
name="edit"
id={`label-${index + 1}`}
onChange={() => toggle(index)}
/>
</label>
<label className="far fa-trash"></label>
</>
) : (
<>
<label className="far fa-circle-check"></label>
<label className="far fa-times-circle" htmlFor={`label-${index + 1}`}>
<input
type="radio"
name="edit"
id={`label-${index + 1}`}
onChange={() => toggle(index)}
/>
</label>
</>
)}
</div>
</td>
</tr>
);
}
Upvotes: 1