How to render Formik Field as textarea + styled-components?

Viewed 11025

I am working with styled-components and Formik. Everything is working well except textareas or selects etc. Styled-components and Formik have got same attribute as and when I want to connect this I am getting not expected results.

<StyledTextArea as={Field} placeholder="" name="topic" id="topic"></StyledTextArea>

Using Formik we need to pass an attribute as for Field element as well. It should looks like this:

<Field as="textarea" id="topic" name="topic"></Field>

I fixed this with writing this:

const StyledTextareaField = (props) => (
    <Field {...props} as="textarea" id="description" name="description" children={props.children}></Field>
  );

and this:

<StyledTextArea
              as={StyledTextareaField}
              placeholder="Wpisz opis spotkania"
              id="description"
              name="description"
            ></StyledTextArea>

But my problem is that when I start typing after one letter I am losing focus from textarea and I must click once again to fill next letter etc.

1 Answers

The problem with losing focus after typing just one character is because of the component is newly created and mounted in DOM after each render.

You can prevent it by wrapping you component with React.memo().

A formik field component can be written as follows:

import {Field} from "formik";
import React from "react";

function MyFormikTextareaField({fieldName}){
  return (
    <Field name={fieldName}>
      {({field, form, meta}) => {
        return (
            <MyStyledTextareaComponent
              value={field.value}
              onChange={field.onChange}
            />
        );
      }}
    </Field>
  )
}

If you prefer to use React hooks, then you can write something like:

function MyFormikTextareaField({fieldName}) {
  const [field, meta, helpers] = useField(fieldName);

  return (
    <MyStyledTextareaComponent
      value={meta.value}
      onChange={field.onChange}
    />
  );
}
Related