Custom Components in Formik
Tags: react, formik, reacthooks
Published: 2020-04-14 11:40:53

---
title: Custom Components in Formik
published: true
date: 2019-08-15 00:00:00 UTC
tags: React,Formik,react-hooks
canonical_url: https://hceris.com/custom-components-in-formik/
---

[![React is like Angular, but totally different](https://hceris.com/static/96887b08014b3bd3c76a5a5b0a865292/3684f/react.png "React is like Angular, but totally different")](/static/96887b08014b3bd3c76a5a5b0a865292/3684f/react.png)

Forms and [React](https://reactjs.org/). Don’t they go well together? If you are doing any serious _React_ development, you will build sooner or later a complex form. The temptation to roll your own homemade framework can arise, but you have to fight it. There are plenty of good existing solutions to pick.

You might choose [Formik](https://jaredpalmer.com/formik/) for the task. In that case, I want to show you how to build a custom input component for it.

## Wait, Formik?

_Formik_ is the new [cool kid on the block](https://jaredpalmer.com/formik/). Quoting the official docs:

> Build forms in React, without the tears.

I certainly share the tears part. I used to build my forms with [redux](https://redux.js.org), using [react-redux-form](https://github.com/davidkpiano/react-redux-form). It is a fine library, don’t get me wrong, but in the end there is a lot of friction connecting things together. Not to mention dealing with the state. Why, anyways? Looking back, having the state of my forms in _Redux_ did not seem to help me that much.

_Formik_ takes a very different approach. It is declarative, relying on pure _React_. It uses [render props](https://reactjs.org/docs/render-props.html), a pattern that is spreading quickly across the _React_ ecosystem. Speaking of that, [this article](https://www.robinwieruch.de/react-render-props-pattern/) helped me finally understand them better.

Anyways, my impression thus far has been that _Formik_ stays out of the way and allows you to focus on building your forms.

## Customization

Regular `input` components, with a sprinkle of styling on top, will get you very far. They cover most typical use cases. But what if you want to spice it up?

For example, I have a small app where I want to give a star rating, from one to five. I implemented it first with a regular number input, which felt boring. I wanted to click on the stars, something like this:

[![Everybody wants to be a star](https://hceris.com/static/de712265dbc0134757a2710f7de95326/34ea4/stars.png "Everybody wants to be a star")](/static/de712265dbc0134757a2710f7de95326/34ea4/stars.png)<figcaption>
  Rate it!
  </figcaption>

How does _Formik_ fare when building something like this? More after the break.

## Representational component

Before we get into the actual form stuff, let’s build the `Stars` as a component for display. We are building a row of five stars. We have a prop (`count`) to set the number of stars that are set as full, and a handler (`handleClick`) to know when a particular star is clicked.

```jsx
const Stars = ({ count, handleClick }) => (
  <span className={styles.stars}>
    {[...Array(5).keys()].map(i => (
      <Star key={i} isFull={i < count} onClick={() => handleClick(i + 1)} />
    ))}
  </span>
);
```

The `Star` component is a thin wrapper around a [Font Awesome](https://fontawesome.com/) clickable icon.

## Custom input component

We are finally getting to the meaty part. How do we make the `Stars` component _Formik_ aware?

We will be rendering our `Stars` representational component inside a [Field](https://jaredpalmer.com/formik/docs/api/field). It uses render props as well, which we’ll use to connect it to our `Stars`.

There is a `field` hash that contains the `value`, aka the number of set stars. That will be the input for `count`. To update the the value after a click on a star, we use the `setFieldValue` function inside the `form` hash. That will update the value internally on _Formik_.

```jsx
const fieldName = "stars";

const StarsInput = () => (
  <Field name={fieldName} id={fieldName} type="number">
    {({ field: { value }, form: { setFieldValue } }) => (
      <div>
        <label htmlFor={fieldName} className={"label-color"}>
          {fieldName}
        </label>
        <div>
          <Stars
            count={value}
            handleClick={number => setFieldValue(fieldName, number)}
          />
        </div>
      </div>
    )}
  </Field>
);
```

## Integrating it into a form

Now that we have our custom input component ready, we can render it inside a regular _Formik_ form, and we are all set:

```jsx
const MyForm = () => {
  return (
    <section>
      <Formik
        onSubmit={onSubmit}
        initialValues={{ stars }}
      >
        {() => (
          <Form>
            <StarsInput />
            <button type="submit">Submit</button>
          </Form>
        )}
      </Formik>
    </section>
  );
};
```

## Codesandbox

You can play with a working implementation of this in the sandbox below. Check it out and extend it to fit your needs.

{% codesandbox laughing-cookies-2t80u %}