i have a scenario where based on a number(say numberOfFlags) i want to render numberOfFlags times an radio button group.Each group has two radio buttons approve and reject as per screen
shot attached how to get values of all inputs when they change?
An lastly i have to store result of all radio buttons (approve/reject) in an array and send to API
Add a comment
|
3 Answers
You can achive this in many different ways, but I would probably simple create a state with an array of values in the parent component and pass it to each and every item to toggle its own state depending action.
App.js
export function App() {
const [list, setList] = useState([false, false, false]);
const updateItem = (value, index) => {
let copyList = [...list];
copyList[index] = !value;
setList(copyList);
};
console.log(list)
return (
<div className="App">
{list && (
<>
{list.map((value, index) => (
<Item values={[value, index]} updateItem={updateItem} key={index+"_check"} />
))}
</>
)}
</div>
);
}
Item.js
export default function Item({ values, updateItem }) {
return (
<>
<input
onChange={() => updateItem(values[0], values[1])}
type="checkbox"
checked={values[0] ? "checked" : ""}
/>
</>
);
}
Comments
Presented below is one possible way to achieve the desired objective.
Code Snippet
const {useState} = React;
const Thingy = ({...props}) => {
// num-of-flags is obtained from props
const { numOfFlags: nf} = props || {};
// if it is null or not above 0, return "invalid" message to parent
if (!(nf && nf > 0)) return "invalid num-of-flags";
// state variable to store approve/reject status
const [statusObj, setStatusObj] = useState({});
// JSX to render the UI & handle events
return (
<div>
{([...Array(nf).keys()].map(grpIdx => (
<div className="grpBox">
Group num {grpIdx+1} <br/>
<input type='radio' name={grpIdx} id={grpIdx} value={'approve'}
onChange={() => setStatusObj({
...statusObj, [grpIdx]: 'approve',
})}
/>
<label for={grpIdx}>Approve</label>{" "}
<input type='radio' name={grpIdx} id={grpIdx} value={'reject'}
onChange={() => setStatusObj({
...statusObj, [grpIdx]: 'reject',
})}
/>
<label for={grpIdx}>Reject</label>
</div>
)))}<br/>
<button
onClick={() => {
// make API call here
// for verification, displaying an alert-message showing the status
const displayMsg = [...Array(nf).keys()].map(
gi => "Group num " + (+gi+1) + " : " + (gi in statusObj ? statusObj[gi] : '__')
).join(', ');
alert(`Approve-Reject status is: ${JSON.stringify(displayMsg)}`);
}}
>
Submit
</button>
</div>
);
};
ReactDOM.render(
<div>
<div className="demoTitle">DEMO</div>
<Thingy numOfFlags={5} />
</div>,
document.getElementById("rd")
);
.demoTitle {
margin-bottom: 5px;
font-size: 20px;
text-decoration: underline;
}
.grpBox {
margin: 5px; padding: 10px;
border: 2px solid purple;
width: max-content;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="rd" />
Explanation
Inline comments added to the snippet above.
PS: If you'd like to add value to stackoverflow community,
2 Comments
Rohit Rai
i want to store these values in an array instead of object.how can i do that??
jsN00b
what should the value be when neither approved, nor rejected are selected? And, what should each element of the array be - should they be just string (like
approved, rejected) or should they be object (like {optionId: 0, status: 'approved'}).