I am learning typescript + react. I have the following form using reactjs and boostrap:
function ControlGroup(props: ControlGroupProps) {
const [agentSettings, setAgentSettings] = useState("");
const [agentQuestion, setAgentQuestion] = useState("");
return (
<Form
onSubmit={(event) =>
props.onAskAgent(props.agentData, agentSettings, agentQuestion, event)
}
>
<Form.Group className="mb-3" controlId="agentForm.settings">
<Form.Label>Set your agent settings</Form.Label>
<Form.Control
as="textarea"
rows={3}
onChange={({ target: { value } }) => setAgentSettings(value)}
value={agentSettings}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="agentForm.question">
<Form.Label> Ask your question </Form.Label>
<Form.Control
as="textarea"
rows={3}
onChange={({ target: { value } }) => setAgentQuestion(value)}
value={agentQuestion}
/>
</Form.Group>
<Button className="center" type="submit">
Ask agent
</Button>
</Form>
);
}
I have two different things I need to capture, agentSettings and agentQuestion. The code below works but I don't like how I have to type:
{({ target: { value } }) => setAgentSettings(value)}
and then
{({ target: { value } }) => setAgentQuestion(value)}
The code is almost identical other than the last bit. Is there a more elegant way to do this in react?
Valid question. Especially, when there are 10 input fields, you don't want to write the same code 10 times.
What's considered "standard" in this case is to use an object for storing form values and use one event handler for all input field changes, by using name
attribute.
Something like this:
const [formData, setFormData] = useState({
inputA: '',
inputB: '',
});
...
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
};
};
...
<input name="inputA" value={formData.inputA} onChange={handleChange} />