如何将 Formik Field 渲染为文本区域 + 样式组件?

Fre*_*e09 8 javascript reactjs styled-components formik

我正在使用 styled-components 和 Formik。除了文本区域或选择等之外,一切都运行良好。Styled-components 和 Formik 具有相同的属性as,当我想连接它时,我得到的不是预期的结果。

<StyledTextArea as={Field} placeholder="" name="topic" id="topic"></StyledTextArea>
Run Code Online (Sandbox Code Playgroud)

as使用 Formik,我们还需要传递 Field 元素的属性。它应该看起来像这样:

<Field as="textarea" id="topic" name="topic"></Field>
Run Code Online (Sandbox Code Playgroud)

我通过写这个解决了这个问题:

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

和这个:

<StyledTextArea
              as={StyledTextareaField}
              placeholder="Wpisz opis spotkania"
              id="description"
              name="description"
            ></StyledTextArea>
Run Code Online (Sandbox Code Playgroud)

但我的问题是,当我在一个字母后开始输入时,我失去了文本区域的焦点,我必须再次单击才能填充下一个字母等。

anh*_*uan 6

仅输入一个字符后失去焦点的问题是因为该组件是在每次渲染后新创建并安装在 DOM 中的。

您可以通过使用 React.memo() 包装组件来防止它。

一个formik字段组件可以写成如下:

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>
  )
}
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢使用 React hooks,那么您可以编写如下内容:

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

  return (
    <MyStyledTextareaComponent
      value={meta.value}
      onChange={field.onChange}
    />
  );
}
Run Code Online (Sandbox Code Playgroud)