React Formik + styled-components

William Whatley
Parakeet Design
Published in
6 min readJul 14, 2018

How I leverage the Formik library alongside styled-components for simple frontend validation.

For those of you who have not used Formik or styled-components, I highly recommend giving them a shot. The two are powerful lightweight libraries for React, and streamline how you handle forms and styles. I’ll briefly explain what they do and how I use them in tandem for frontend form validation.

By the end of this article, we’ll have a fully functional React form complete with dynamic frontend validation and styling.

Styled-components

Styled-components has quickly become my favorite library for React, so much so, that when I watch a tutorial and it’s not being implemented, I cringe slightly. In styled-component’s words:

“Use the best bits of ES6 and CSS to style your apps without stress”

That’s great and all, but what does this mean? It means that you can encapsulate css styles in components and reuse (compose) them throughout your app. The added benefit here, is that you can create themed elements that have a single origin in your application. So if you need to change certain elements at various times, you only have to change it in one place!

Also, if you’re like me, nested div upon nested div upon nested div brings out the inner lunatic.

Above, I have a component called Title that I’m tacking on css styles through back ticks ``. Because I’m specifying that it’s a h1 element, it will compile down as such.

Now I can use it:

Of course, this isn’t limited to just h1 , you can use styled-components for any HTML element including div , form , input , label , section , and so on!

This isn’t all there is to styled-components, or it probably wouldn’t be so helpful. In situations where you need dynamic css styles, you can do so with ease.

Let’s say I have a theme document for my application, which has all of my reusable, styled components.

You can see here, I have a couple styled text elements, a form, button, and an input. The input currently has a static border of 1px solid #ccc which creates a gray border.

I can use my styled-components in tandem and create a form like so:

Above I have a basic form with a couple inputs and a button element that I’ve styled in my theme document.

Now for the fun part — what if I wanted to display a red border if the user enters incorrect information? With styled-components, it’s easy, because you can declare dynamic props which can be used with your elements.

Above, I’ve changed the static border value to dynamic by adding a prop that I’m calling border , and then setting a default value by using || (or) and then passing a string value of 1px solid #ccc — same has the static value declared before.

Now I have access to the border prop and can use it in my form:

As you can see above, my input now is utilizing its border prop — I’m using the logical && operator to check if errors.email or errors.password is true, and if so, I’m telling it to have a red border instead of its default gray border. Currently errors is undefined, but I wanted to illustrate how it works.

A red border is a start, but wouldn’t it be a better user experience if we printed the error so the user knows what went wrong?

Above, I have defined a styled-component above my class component called label , which is as you guessed, a HTML label tag under the hood. Inline with my label element, I have the same conditional statement checking if errors.email or errors.password is true, and if so, print the error in my styled-component Text component, which is also utilizing a custom dynamic prop color to display as red text!

Pretty cool, huh? This is only a small example of what you can do with styled-components.

Formik

In the author Jared Palmer’s words, “Build forms in React, without the tears 😭.”

Formik is a lightweight form handling library that assists with retrieving values in and out of form state, helps with validation and error handling and form submission. React out-of-the-box comes with everything you need to build forms yourself, but the problem is, by the time you create all of your event handlers, it’s essentially a library, and you now need to maintain that library — better to leave that to a package with a strong following and contribution network, which Formik has.

You can use Formik two ways:

  • As a higher-order component (HOC)
  • Or with<Formik /> which is a React component that you can wrap your form with a render prop.

It’s completely up to you with which pattern your prefer — I typically use the <Formik /> component with render prop, which I’ll demonstrate for the purpose of this article.

Between lines 11–53, you can see that I’m using the <Formik /> component top wrap my own form. There is a lot going on here, so let’s break it down.

The <Formik /> component has a few props that I’m using:

  • initialValues={{email: '', password: ''}} — similar to a class constructor, initialValues is where you initialize your form’s state by providing initial instance state. In this case, I’m initializing email and password with empty strings because I do not want the input fields to have initial values. If you need your input values to have default values, you can pass it an object as a prop too.
  • validate={values => {}} — this is really the bread and butter of what makes Formik so useful; the validate prop gives you access to values of controlled inputs and runs on every onChange. We’ll discuss this further later.
  • render={({touched, errors, values, handleChange, handleBlur, handleSubmit}) => ()} — this is what is referred to as a render prop. I’m passing a few helpers and methods: touched — keeps track of input fields that have been touched/visited. errors — gives you access to the errors object, which is how we’ll keep track of validation errors (side note: errors must match the shape of your form’s values defined in initialValues ). values — your form’s input values. handleChange, handleBlur, handleSubmit — reusable methods that control form submission and values.

With the render prop, I’m able to wrap my form and have access to the above helpers and methods.

Now the input elements are utilizing the power of Formik and its helpers — by using the input’s value attribute, I can programmatically link the input to the form’s state with Formik’s values object. Formik’s handleChange method will grab what’s entered into the form’s input and expose it to state — it’s now accessible in the <Formik /> component’s validate and onSubmit props.

Let’s see what that looks like:

Above, in validateI’m grabbing form values by passing values as an argument, then declaring an empty object called errors — next I’m writing custom validation with regular expressions and checking if the acceptable length has been met. Once the validation tests have ran, it’ll return all errors in the errors object, which is accessible in <Formik /> component’s render prop.

The onSubmit prop is just logging the values for now, but you can do anything here! Currently, it’s printing {email: '', password: ''} , but of course this will update when you submit the inputs with form values. Typically, this is where I send form values with a Redux action.

The last thing to do now is utilize touched , which returns whether or not a field has been touched/visited.

Now I’m using touched , and with styled-components in tandem, I’m conditionally rendering a red border around my input elements when touched is true (user has visited the input), and errors is true (validate has ran and returned an error based upon my tests).

And there you have it! That’s the complete form with styled-components and Formik! This is meant to be a small example, so you can only imagine the endless possibilities with the two libraries in harmony.

Thank you for reading! I’m always open to suggestions/feedback, and greatly appreciate positive criticism.

If you enjoyed the article, please hold down the applause button and give me 50 claps!

--

--

William Whatley
Parakeet Design

React, React Native, Node, AWS; Mentor & Mentee; Indie Video Game Dev; Co-Founder @ Parakeet