albertofortes

UI engineer | front-end React developer

JavaScript, #100DaysOfGatsby, Gatsby, forms, Formik,

How to add a form in your Gatsby React site..

2020-01-25

How to add a form in your Gatsby React site..

Adding a contact Form using Formik. Belongs to Challenge 4 - Add Third-Party React Components to Your Gatsby Site.

This Challenge is about learning to add React components to your Gatsby sites, and specifically adding a contact form with the Formik React Library into your site.

Installing Formik library.

First at all install the npm into your site folder:

1npm i formik

Now create a new contact.js page, adding import { useFormik } from 'formik' there:

1import React from "react" 2import { useStaticQuery, Link, graphql } from "gatsby" 3import PropTypes from "prop-types" 4import Layout from "../components/layout" 5import SEO from "../components/seo" 6import { useFormik } from 'formik'; 7 8const ContactPage = ({ children }) => { 9 const data = useStaticQuery(graphql` 10 { 11 site { 12 siteMetadata { 13 title 14 role 15 description 16 } 17 } 18 } 19 `) 20 21 return ( 22 <Layout> 23 <SEO title="Contact me" description={data.site.siteMetadata.description} /> 24 <article className="article"> 25 <h2 className="article__title article__title--remark t-c">I’m Alberto Fortes, Front-end developer. Drop me a few lines!</h2> 26 <div className="article__cont"> 27 TO DO: FORM 28 </div> 29 </article> 30 </Layout> 31 ) 32} 33 34ContactPage.propTypes = { 35 children: PropTypes.node.isRequired, 36} 37 38export default ContactPage

We can add form now. The result will be this:

My form

The HTML (JSX) would be:

1<form className="genericforms" onSubmit={formik.handleSubmit}> 2{ ( (formik.touched.your_name && formik.errors.your_name) || (formik.touched.your_email && formik.errors.your_email) || (formik.touched.your_message && formik.errors.your_message) ) 3 ? <div className="genericforms__alert"> 4 { formik.errors.your_email ? (<p>{formik.errors.your_email}</p>) : null } 5 { formik.errors.your_name ? (<p>{formik.errors.your_name}</p>) : null } 6 { formik.errors.your_message ? (<p>{formik.errors.your_message}</p>) : null } 7 </div> 8 : null 9} 10 11<div className="genericforms__field"> 12 <label className="sr-only" htmlFor="your_email">Your Email address</label> 13 <input className="genericforms__field__text" placeholder="Type your Email address" id="your_email" name="your_email" type="email" onChange={formik.handleChange} value={formik.values.your_email} /> 14</div> 15<div className="genericforms__field"> 16 <label className="sr-only" htmlFor="your_name">Your Name</label> 17 <input className="genericforms__field__text" placeholder="What's your name?" id="your_name" name="your_name" type="text" onChange={formik.handleChange} value={formik.values.your_name} /> 18</div> 19<div className="genericforms__field genericforms__field--one-row"> 20 <label className="sr-only" htmlFor="your_message">Your message</label> 21 <textarea className="genericforms__field__text" placeholder="Your message" id="your_message" name="your_message" onChange={formik.handleChange} value={formik.values.your_message} /> 22</div> 23<div className="genericforms__field genericforms__field--one-row"> 24 <button className="genericforms__field__btn" type="submit">Submit</button> 25</div> 26</form>

And above that, before the render method, we need to add some JavaScript to configure Formik:

1const ContactPage = ({ children }) => { 2 […] 3 const validate = values => { 4 const errors = {}; 5 if (!values.your_name) { 6 errors.your_name = 'Your name is a required field.'; 7 } 8 9 if (!values.your_message) { 10 errors.your_message = 'Message required.'; 11 } else if (values.your_message.length < 15) { 12 errors.your_message = 'Must be 15 characters at least.'; 13 } 14 15 if (!values.your_email) { 16 errors.your_email = 'Your email is a required field'; 17 } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.your_email)) { 18 errors.your_email = 'Invalid email address.'; 19 } 20 21 return errors; 22 }; 23 24 // Pass the useFormik() hook initial form values and a submit function that will be called when the form is submitted 25 const formik = useFormik({ 26 initialValues: { 27 your_email: '', 28 your_name: '', 29 your_message: '', 30 }, 31 validate, 32 onSubmit: values => { 33 alert(JSON.stringify(values, null, 2)); 34 }, 35 }); 36 37 return ( 38 […] 39 ) 40}