Chakra UI + Formik
The way we start building forms with Formik is by using
its useFormik
hook that returns us the formik instance. That Formik instance
contains pretty much everything we need to connect our form's UI elements and
submit handler. Let's see a pure React + Formik example:
import { useFormik } from "formik"; const App = () => { // Pass the useFormik() hook initial form values and a submit function that will // be called when the form is submitted const formik = useFormik({ initialValues: { email: '', }, onSubmit: (values) => { alert(JSON.stringify(values, null, 2)) }, }) return ( <form onSubmit={formik.handleSubmit}> <label htmlFor='email'>Email Address</label> <input id='email' name='email' type='email' onChange={formik.handleChange} value={formik.values.email} /> <button type='submit'>Submit</button> </form> ) } export default App;
As you can see from the example above, our formik
instance contains the
handleSubmit
, handleChange
, and values
, and we use them to handle the
submit event, handle all of the change events, and keep the values in a single
variable.
Introducing Chakra UI into the mix is very straightforward! If we were to
replace the input
element in the example above with a Chakra UI Input
component, everything will work the same!
import { useFormik } from "formik"; import { Input, Button } from "@chakra-ui/react"; const SimpleFormik = () => { const formik = useFormik({ initialValues: { email: '', }, onSubmit: (values) => { alert(JSON.stringify(values, null, 2)) }, }) return ( <form onSubmit={formik.handleSubmit}> <label htmlFor='email'>Email Address</label> <Input id='email' name='email' type='email' onChange={formik.handleChange} value={formik.values.email} /> <Button type='submit'>Submit</Button> </form> ) } export default SimpleFormik;
Awesome! This means we can continue building our form UI, and just connect Formik's and Chakra UI's events! Let's try to build a bit more complex Login UI:
import { useFormik } from "formik"; import { Box, Button, Checkbox, Flex, FormControl, FormLabel, Input, VStack } from "@chakra-ui/react"; const LoginFormFormik = () => { const formik = useFormik({ initialValues: { email: "", password: "", rememberMe: false }, onSubmit: (values) => { alert(JSON.stringify(values, null, 2)); } }); return ( <Flex bg="gray.100" align="center" justify="center" h="100vh"> <Box bg="white" p={6} rounded="md"> <form onSubmit={formik.handleSubmit}> <VStack spacing={4} align="flex-start"> <FormControl> <FormLabel htmlFor="email">Email Address</FormLabel> <Input id="email" name="email" type="email" variant="filled" onChange={formik.handleChange} value={formik.values.email} /> </FormControl> <FormControl> <FormLabel htmlFor="password">Password</FormLabel> <Input id="password" name="password" type="password" variant="filled" onChange={formik.handleChange} value={formik.values.password} /> </FormControl> <Checkbox id="rememberMe" name="rememberMe" onChange={formik.handleChange} isChecked={formik.values.rememberMe} colorScheme="purple" > Remember me? </Checkbox> <Button type="submit" colorScheme="purple" width="full"> Login </Button> </VStack> </form> </Box> </Flex> ); } export default LoginFormFormik;
What about validation? And what about using the Formik
component instead of
the useFormik
hook? Here's a modified example of the Login UI that uses the
Formik
component with password validation implemented:
import { Formik, Field } from "formik"; import { Box, Button, Checkbox, Flex, FormControl, FormLabel, FormErrorMessage, Input, VStack } from "@chakra-ui/react"; const LoginFormWithValidationFormik = () => { return ( <Flex bg="gray.100" align="center" justify="center" h="100vh"> <Box bg="white" p={6} rounded="md" w={64}> <Formik initialValues={{ email: "", password: "", rememberMe: false }} onSubmit={(values) => { alert(JSON.stringify(values, null, 2)); }} > {({ handleSubmit, errors, touched }) => ( <form onSubmit={handleSubmit}> <VStack spacing={4} align="flex-start"> <FormControl> <FormLabel htmlFor="email">Email Address</FormLabel> <Field as={Input} id="email" name="email" type="email" variant="filled" /> </FormControl> <FormControl isInvalid={!!errors.password && touched.password}> <FormLabel htmlFor="password">Password</FormLabel> <Field as={Input} id="password" name="password" type="password" variant="filled" validate={(value) => { let error; if (value.length < 5) { error = "Password must contain at least 6 characters"; } return error; }} /> <FormErrorMessage>{errors.password}</FormErrorMessage> </FormControl> <Field as={Checkbox} id="rememberMe" name="rememberMe" colorScheme="purple" > Remember me? </Field> <Button type="submit" colorScheme="purple" width="full"> Login </Button> </VStack> </form> )} </Formik> </Box> </Flex> ); } export default LoginFormWithValidationFormik;
These examples should help you understand how to integrate Chakra UI with Formik.
If you have any questions, or need help around an advanced usage, don't hesitate to reach out in our Discord server.