Freestyle09
Freestyle09

Reputation: 5508

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

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.

Upvotes: 8

Views: 22896

Answers (2)

GM Taium Ahmed
GM Taium Ahmed

Reputation: 107

# use  <textarea/> instead of <input/>

        <input
                          placeholder='description'
                          {...formik.getFieldProps('description')}
                          name='description'
                          className={clsx(
                            'form-control form-control-solid mb-3 mb-lg-0',
                            {'is-invalid': formik.touched.description && formik.errors.description},
                            {
                              'is-valid': formik.touched.description && !formik.errors.description,
                            }
                          )}
                          autoComplete='off'
                          disabled={formik.isSubmitting || loading}
                        />
                        
                        
                        ----------------
                        

     <textarea
                          placeholder='description'
                          {...formik.getFieldProps('description')}
                          name='description'
                          className={clsx(
                            'form-control form-control-solid mb-3 mb-lg-0',
                            {'is-invalid': formik.touched.description && formik.errors.description},
                            {
                              'is-valid': formik.touched.description && !formik.errors.description,
                            }
                          )}
                          autoComplete='off'
                          disabled={formik.isSubmitting || loading}
                        />

`

Upvotes: 0

anhquan
anhquan

Reputation: 1398

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}
    />
  );
}

Upvotes: 6

Related Questions