使用自定义组件时不会触发 onChange 处理程序

A7D*_*7DC 3 javascript forms onchange reactjs formik

我在 React 应用程序中使用Formik进行验证。

验证工作正常,但我的 onChange 处理程序没有触发:

  <Field
    type="text"
    name="name"
    placeholder="First Name"
    component={Input}
    onChange={() => console.log("gfdg")}
  />
Run Code Online (Sandbox Code Playgroud)

沙盒链接

为什么是这样?

Mad*_*one 8

在里面Input,您对传递给 input 元素的 props 进行排序的方式意味着您onChange正在被 Formik 的onChange. 当您Field使用自定义组件创建 a时(即Input在您的情况下),Formik 将其传递FieldProps给组件。FieldProps包含一个field包含各种处理程序的属性,包括onChange.

在你的Input组件中你这样做(我已经删除了不相关的道具):

<input
    onChange={onChange}
    {...field}
/>
Run Code Online (Sandbox Code Playgroud)

看看您自己的onChange将如何被 Formik 的onChange()内部所取代field?为了更清楚...field,基本上是导致这种情况发生:

<input
    onChange={onChange}
    onChange={field.onChange}
    // Other props inside "field".
/>
Run Code Online (Sandbox Code Playgroud)

如果您要重新排序,控制台消息现在将出现:

<input
    {...field}
    onChange={onChange}
/>
Run Code Online (Sandbox Code Playgroud)

但是,现在您的输入将不起作用,因为您确实需要onChange在输入更改时立即调用 Formik以让 Formik 生效。如果您希望自定义onChange事件和输入都能正常工作,您可以这样做:

import React from "react";
import { color, scale } from "./variables";

const Input = React.forwardRef(
  ({ onChange, onKeyPress, placeholder, type, label, field, form }, ref) => (
    <div style={{ display: "flex", flexDirection: "column" }}>
      {label && (
        <label style={{ fontWeight: 700, marginBottom: `${scale.s2}rem` }}>
          {label}
        </label>
      )}
      <input
        {...field}
        ref={ref}
        style={{
          borderRadius: `${scale.s1}rem`,
          border: `1px solid ${color.lightGrey}`,
          padding: `${scale.s3}rem`,
          marginBottom: `${scale.s3}rem`
        }}
        onChange={changeEvent => {
          form.setFieldValue(field.name, changeEvent.target.value);
          onChange(changeEvent.target.value);
        }}
        onKeyPress={onKeyPress}
        placeholder={placeholder ? placeholder : "Type something..."}
        type={type ? type : "text"}
      />
    </div>
  )
);

export default Input;
Run Code Online (Sandbox Code Playgroud)

在这里看到它的行动

虽然总的来说我不太确定你想要做什么。您的表单工作正常,您可能不需要自定义,onChange但也许您有一些特定的用例。