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?
2
Answers
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:
I think the best approach when dealing with forms is to use Formik and Yup.
Formik is the most popular open source form library for React. It saves you lots of time when building forms and offers a declarative, intuitive and adoptable paradigm.
Yup is an open-source library that integrates perfectly with Formik. It allows you to set all your form validation rules declaratively.
First install both libraries:
After that:
The below code would go inside a React.JS component:
The way you would use this function is by spreading the returned object into the input elements:
Using TypeScript there are a few changes.
Here you can find Formik TypeScript Support with a very good example for what you’re looking for: https://formik.org/docs/examples/typescript
Here you can find Yup TypeScript Support: https://github.com/jquense/yup/blob/pre-v1/docs/typescript.md