Setup is a nice library to speed up the process of creating forms in . It handles all the basic functionality like the form state, validation and submission. Formik React Let's begin by creating an empty https://create-react-app.dev/ create-react-app npx create-react-app my-app Install the formik library yarn add formik Using formik components Remove the example code generated and import the formik library and some components in App.js. We will use the react just to show the values of the form in this example. useState hook React, { useState } { Formik, Form, Field } App() { const [result, setResult] = useState( ) ( // Formik the main component that handles the logic // Form just a regular html <form> <Formik> {() => ( <Form> </Form> )} </Formik> ); } export App import from 'react' import from 'formik' function '' return is all is wrapper default Let's use the formik component to create some fields. Check the docs to see all possible props available Field https://jaredpalmer.com/formik/docs/api/field#props-1 A default Field is an type="text" input <Field = /> name "fieldName" For the select, we specify the options as children <Field ="select" ="color" ="none"> < ="none">Pick a color</ > < ="red">Red</ > < ="green">Green</ > < ="blue">Blue</ > </Field> as name value option value option option value option option value option option value option In this example we are going to use a to show the values after submit textarea <Field = ={result} rows={ } /> as "textarea" value 5 Form props are passed down to children giving many options for custom fields < = > Field name "email" {({ field }) => ( <div> <label>email:</label> <input type="email" required placeholder="Email" {...field} /> </div> )} </ > Field We can go further and just set a component prop. Form props will passed to this component { <Field name="name" required placeholder="Name" component={CustomInput} /> ( ) function CustomInput { field, form, ...props } return } < { } { } /> input ...field ...props A will automatically handle form type="submit" onSubmit Submit < = > button type "submit" </ > button Put everything together This is the final example form created with formik. needs the prop to work properly. Formik initialValues import React, { useState } from 'react' import { Formik, Form, Field } from 'formik' function CustomInput({ field, form, ...props }) { return } function App() { const [result, setResult] = useState('') return ( { setResult(JSON.stringify(values)) }} > {() => ( Pick a color Red Green Blue {({ field }) => ( email: )} Submit )} ) } export default App < { } { } /> input ...field ...props < = '', '', ' ' }} = ) => Formik initialValues {{ email: name: color: red onSubmit {(values, actions < > Form < = = = > Field as "select" name "color" value "none" < = > option value "none" </ > option < = > option value "red" </ > option < = > option value "green" </ > option < = > option value "blue" </ > option </ > Field < /> br < = > Field name "email" < > div < > label </ > label < = = { } /> input type "email" required placeholder "Email" ...field </ > div </ > Field < /> br < = = = /> Field name "name" required placeholder "Name" component {CustomInput} < /> br < = > button type "submit" </ > button < /> br < /> br < = ' %'}} = = = /> Field style {{ width: 100 as "textarea" value {result} rows {2} </ > Form </ > Formik Not so fancy, but I didn't wanted to pollute the code with styling. Unit testing with React Testing Library Normally it's enough to use and to test components, but with , internal React and get more complex under the hood and a simple doesn't work. Luckily there's a nice piece of software called that has support for many frontend libraries and frameworks Jest Enzyme Formik state events input.simulate('change') Testing Library https://testing-library.com/docs/intro First of all, install the library as dev dependency yarn add --dev '@testing-library/react' Test if the App doesn't crash first it( , () => { div = .createElement( ) ReactDOM.render( 'renders without crashing' const document 'div' , div) }) < /> App Now let's pick all the field elements to be able to fire events with them it( , () => { { container } = render( 'submits correct values' const ) const name = container.querySelector('input[name="name"]') const email = container.querySelector('input[name="email"]') const color = container.querySelector('input[name="color"]') const submit = container.querySelector('button[type="submit"]') }) < /> App Let's change their values fireEvent.change(name, { : { : } }) fireEvent.change(email, { : { : } }) fireEvent.change(color, { : { : } }) target value 'mockname' target value 'mockemail' target value 'mockcolor' We get this error Warning: An update to Formik inside a test was not wrapped act(...). When testing, code that causes React state updates should be wrapped into act(...): act( { }); in => () /* fire events that update state */ /* assert on the output */ This means that something changed inside the test, we need to wait for these changes. is also good, but instead of , we can also use Testing Library's Formik state act act wait https://testing-library.com/docs/dom-testing-library/api-async#wait Notice that we will change the test to async it( , () => { { container } = render( "submits correct values" async const ) const name = container.querySelector('input[name="name"]') const email = container.querySelector('input[name="email"]') const color = container.querySelector('select[name="color"]') const submit = container.querySelector('button[type="submit"]') const results = container.querySelector("textarea"); await wait(() => { fireEvent.change(name, { target: { value: "mockname" } }) }) await wait(() => { fireEvent.change(email, { target: { value: "mock@email.com" } }) }) await wait(() => { fireEvent.change(color, { target: { value: "green" } }) }) await wait(() => { fireEvent.click(submit) }) expect(results.innerHTML).toBe( '{"email":"mock@email.com","name":"mockname","color":"green"}' ) }) < /> App Now we get the correct results and thanks to Testing Library we focus on functionality and DOM behavior instead of dealing with React details. You can go further and read Formik documentation to create complex forms and Fields. Thanks for reading. UPDATE: Testing Library 'wait' is deprecated now. Use 'waitFor' instead.