使用 Formik 并包装 Material TextField 导致按键模糊

Using Formik and wrapping Material TextField causing blur on keypress

我不确定我更改了什么以使我的自定义 TextFields 开始以这种方式运行,但我包装了 Material-UI TextFields 以使用 Formik 验证.我已经包含了一个完整的代码沙箱来分叉和使用。

目前,当我键入(或在数字字段的情况下单击 up/down 箭头)时,该字段“模糊”并且我必须重新聚焦每个 keypress 才能继续键入。数字字段导致数字值下降而不是增加。

这是我的自定义 TextField 包装器:

import React from "react";
import { FieldAttributes, useField } from "formik";
import {
  InputBaseComponentProps,
  TextField as MuiTextField
} from "@material-ui/core";

interface TextFieldProps {
  label: string;
  inline?: boolean;
  inputProps?: InputBaseComponentProps;
}

const TextField: React.FC<FieldAttributes<TextFieldProps>> = ({
  inline = false,
  ...props
}) => {
  const { type, label, placeholder, inputProps } = props;
  const [field, meta] = useField<TextFieldProps>(props);
  const errorText = meta.error && meta.touched ? meta.error : "";

  const Field = () => (
    <MuiTextField
      {...field}
      label={label}
      variant="outlined"
      margin="dense"
      type={type}
      placeholder={placeholder ? placeholder : label}
      helperText={errorText}
      error={!!errorText}
      inputProps={inputProps}
    />
  );

  return inline ? (
    <Field />
  ) : (
    <div>
      <Field />
    </div>
  );
};

export default TextField;

下面是代码沙箱,以防我的示例代码与我做错的事情无关:

https://codesandbox.io/s/eager-black-jw717

我认为您每次输入文本或关注字段时都在玩 MuiTextField

React 将在功能组件中重新渲染时再次 运行 所有代码,因此 Field() 将再次创建 MuiTextField

要解决这个问题,您可以将 FieldTextField 分成两个部分。

const Field: React.FC<FieldAttributes<TextFieldProps>> = (props) => {
  const { type, label, placeholder, inputProps } = props;
  const [field, meta] = useField<TextFieldProps>(props);
  const errorText = meta.error && meta.touched ? meta.error : "";

  return (
    <MuiTextField
      {...field}
      label={label}
      variant="outlined"
      margin="dense"
      type={type}
      placeholder={placeholder ? placeholder : label}
      helperText={errorText}
      error={!!errorText}
      inputProps={inputProps}
    />
  );
};

const TextField: React.FC<FieldAttributes<TextFieldProps>> = ({
  inline = false,
  ...props
}) => {
  return inline ? (
    <Field {...props} />
  ) : (
    <div>
      <Field {...props} />
    </div>
  );
};

这是代码框:

https://codesandbox.io/s/interesting-rain-8tl14?file=/src/components/TextField.tsx:839-848