Обработчик onChange не срабатывает при использовании пользовательского компонента - PullRequest
0 голосов
/ 03 мая 2019

Я использую Formik для проверки в приложении React.

Проверка работает правильно, но мой обработчик onChange не запускается:

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

Ссылка на песочницу

Почему это?

1 Ответ

1 голос
/ 03 мая 2019

Внутри Input то, как вы заказали реквизиты, передаваемые в ваш элемент ввода, означает, что ваш onChange перезаписывается onChange Formik.Когда вы создаете Field с пользовательским компонентом (например, Input в вашем случае), Formik передает его FieldProps компоненту.FieldProps содержит свойство field, содержащее различные обработчики, включая onChange.

В вашем компоненте Input вы делаете это (я удалил ненужные реквизиты):

<input
    onChange={onChange}
    {...field}
/>

Посмотрите, как ваш onChange будет заменен на onChange() Формика внутри field?Чтобы сделать это более понятным, ...field в основном приводит к тому, что это происходит:

<input
    onChange={onChange}
    onChange={field.onChange}
    // Other props inside "field".
/>

Если вы измените их порядок, появится консольное сообщение:

<input
    {...field}
    onChange={onChange}
/>

Однако сейчасваш ввод не будет работать сейчас, потому что вам нужно вызвать Formik onChange, чтобы позволить 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;

Смотрите его здесь в действии .

Хотя в целом я не совсем уверен, что вы пытаетесь сделать.Ваша форма работает нормально, вам, вероятно, не нужен пользовательский onChange, но, возможно, у вас есть какой-то конкретный вариант использования.

...