'One handle function for multiple inputs on nested object
Can I use a single function to handle all my text field related to a nested object?
Or should I write a single handle function for every nested level?
E.g.:
- a handle function to handle inputs of level 1
- a handle function to handle inputs of level 2
- a handle function to handle inputs of level 3 and so on...
Furthermore... should I need to write a handle function for every different kind of input?
E.g.:
- a handle function to handle input text
- a handle function to handle input dates
- a handle function to handle checkboxes
- a handle function to handle radio buttons
What's the best practice to do this?
import { Card, Row, Col, FloatingLabel, Form, InputGroup, Button, Stack } from "react-bootstrap"
import { useEffect } from "react"
import { useImmer } from "use-immer"
const OccasionalServicesInvoiceDetails = () => {
const [details, setDetails] = useImmer({
num: "",
date: "",
remuneration: "",
remunerationType: "net",
serviceDescription: "",
serviceExecution: [
{
date: "",
timeGroup1: {
enabled: false,
fromHours: "",
toHours: ""
},
timeGroup2: {
enabled: false,
fromHours: "",
toHours: ""
}
}
]
})
// Can I use this function to dynamically handle "details.serviceExecution" array, its nested objects and properties?
// I'm using Immer to update the nested properties
// I'd like to set e.g. "details.serviceExecution[0].date" and "details.serviceExecution[0].timeGroup1.fromHours", etc...
const handleInput = e => setDetails(draft => (draft[e.target.name] = e.target.value))
return (
<div>
{/* {... here there are other input fields: num, date, remuneration, remunerationType, serviceDescription. I cut them off for brevity} */}
{Array.isArray(details.serviceExecution) &&
details.serviceExecution.map((serviceExecutionRow, index) => (
<Row className="my-3 p-2 bg-light" key={index}>
<Col md={4} lg={4} className="mx-auto">
<Stack direction="horizontal" gap={3}>
<Button
type="submit"
variant="secondary"
onClick={handleAddServiceExecutionRow}
>
<FontAwesomeIcon icon={faPlus} />
</Button>
<Button
type="submit"
variant="secondary"
onClick={e => handleRemoveServiceExecutionRow(e, index)}
disabled={details.serviceExecution.length === 1}
>
<FontAwesomeIcon icon={faMinus} />
</Button>
<div className="vr" />
<FloatingLabel label="Data">
<Form.Control
type="date"
name="date"
value={details.serviceExecution[index].date}
onChange={e => handleServiceExecutionRow(e, index)}
/>
</FloatingLabel>
</Stack>
</Col>
<Col md={3} className="mx-auto">
<Stack direction="horizontal" gap={3}>
<Form.Check
inline
name="timeGroup1"
type="checkbox"
id="timeGroup1"
onChange={e => handleServiceExecutionRow(e, index)}
checked={details.serviceExecution[index].timeGroup1.enabled}
className="fs-4"
/>
<FloatingLabel label="dalle ore">
<Form.Control
type="time"
name="timeGroup1"
id="fromHours"
step="900"
value={details.serviceExecution[index].timeGroup1.fromHours}
disabled={
!details.serviceExecution[index].timeGroup1.enabled
}
onChange={e => handleServiceExecutionRow(e, index)}
/>
</FloatingLabel>
<FloatingLabel label="alle ore">
<Form.Control
type="time"
name="timeGroup1"
id="toHours"
step="900"
value={details.serviceExecution[index].timeGroup1.toHours}
disabled={
!details.serviceExecution[index].timeGroup1.enabled
}
onChange={e => handleServiceExecutionRow(e, index)}
/>
</FloatingLabel>
</Stack>
</Col>
<Col md={3} className="mx-auto">
<Stack direction="horizontal" gap={3}>
<Form.Check
inline
name="timeGroup2"
type="checkbox"
id="timeGroup2"
// onChange={e => handleServiceExecutionTimeGroups(e, index)}
checked={details.serviceExecution[index].timeGroup2.enabled}
className="fs-4"
/>
<FloatingLabel label="dalle ore">
<Form.Control
type="time"
name="timeGroup2"
id="fromHours"
step="900"
value={details.serviceExecution[index].timeGroup2.fromHours}
disabled={
!details.serviceExecution[index].timeGroup2.enabled
}
// onChange={e => handleServiceExecutionTimeGroups(e, index)}
/>
</FloatingLabel>
<FloatingLabel label="alle ore">
<Form.Control
type="time"
name="timeGroup2"
id="toHours"
step="900"
value={details.serviceExecution[index].timeGroup2.toHours}
disabled={
!details.serviceExecution[index].timeGroup2.enabled
}
// onChange={e => handleServiceExecutionTimeGroups(e, index)}
/>
</FloatingLabel>
</Stack>
</Col>
</Row>
))}
</div>
)
}
export default OccasionalServicesInvoiceDetails
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
