简体   繁体   English

在 React 钩子中,使用 setValue() 的 handleChange 中没有 e.target

[英]In React hook, no e.target in handleChange with setValue()

Since I'm learning how to build React forms with hooks, I went through the 3 quicks posts that culminate with this one .由于我正在学习如何使用钩子构建 React 表单,因此我浏览了 3 篇快速文章, 这些文章最终以 . Everything is going well until I get to the last step when you create your custom hook with:一切都很顺利,直到我使用以下命令创建自定义挂钩时进入最后一步:

function useFormInput(initialValue) {
  const [value, setValue] = useState(initialValue);

  function handleChange(e) {
    setValue(e.target.value);
  }

  return {
    value,
    onChange: handleChange
  };
}

The Input is:输入是:

const Input = ({ type, name, onChange, value, ...rest }) => (
    <input
        name={name}
        type={type}
        value={value}
        onChange={event => {
            event.preventDefault();
            onChange(name, event.target.value);
        }}
        {...rest}
    />
);

And the Form is:表格是:

const Form = () => {
  const email = useFormInput("");
  const password = useFormInput("");

  return (
    <form
      onSubmit={e =>
        e.preventDefault() || alert(email.value) || alert(password.value)
      }
    >
      <Input 
        name="email" 
        placeholder="e-mail" 
        type="email" 
        {...email} 
      />
      <Input
        name="password"
        placeholder="password"
        type="password"
        {...password}
      />
      <input type="submit" />
    </form>
  );
};

So in useFormInput() Chrome complains about所以在useFormInput() Chrome 抱怨

TypeError: Cannot read property 'value' of undefined at handleChange TypeError:无法在句柄更改处读取未定义的属性“值”

which I'm pretty sure is pointing me to我很确定这是指向我

function handleChange(e) {
  setValue(e.target.value);
}

If I console.log(e) I get 'email', as expected (I think?), but if I try console.log(e.target) I get undefined.如果我 console.log(e) 我收到“电子邮件”,正如预期的那样(我认为?),但如果我尝试 console.log(e.target) 我得到未定义。 So obviously e.target.value doesn't exist.所以显然 e.target.value 不存在。 I can get it working by just using我可以通过使用它来工作

setValue(document.getElementsByName(e)[0].value);

but I don't know what kind of issues this might have.但我不知道这可能有什么样的问题。 Is this a good idea?这是一个好主意吗? Are there drawbacks to getting it to work this way?让它以这种方式工作有缺点吗?

Thanks谢谢

The issue comes from the onChange prop in the Input component问题来自Input组件中的onChange道具

    onChange={event => {
        event.preventDefault();
        onChange(name, event.target.value);
    }}

you're calling onChange like this onChange(name, event.target.value);你像这样调用onChange onChange(name, event.target.value); (two arguments, the first one is a string), while in your custom hook you define the callback like this (两个参数,第一个是字符串),而在您的自定义挂钩中,您可以像这样定义回调

  function handleChange(e) {
    setValue(e.target.value);
  }

it's expecting one argument, an event.它期待一个论点,一个事件。

So either call onChange with one argument (the event) :所以要么用一个参数(事件)调用onChange

onChange={event => {
    event.preventDefault();
    onChange(event);
}}

or change the implementation of the callback.或更改回调的实现。

Try this out:试试这个:

const handleChange = e => {
   const { inputValue } = e.target;
   const newValue = +inputValue;
   setValue(newLimit);
};

Had this issue with a calendar picker library react-date-picker using Register API .使用Register API的日历选择器库react-date-picker存在此问题。 Looking at the documentation found out that there's another way of handling components that don't return the original event object on the onChange function using the Controller API .查看文档发现还有另一种方法可以使用Controller API处理不返回onChange函数上的原始事件对象的组件。

More details on Controller API Docs有关控制器 API 文档的更多详细信息

Example:例子:

/*
* React Function Component Example
* This works with either useForm & useFormContext hooks.
*/
import { FC } from 'react'
import { Controller, useFormContext } from 'react-hook-form'
import DatePicker,{ DatePickerProps } from 'react-date-picker/dist/entry.nostyle'


const FormDateInput: FC<Omit<DatePickerProps, 'onChange'>> = ({
  name,
  ...props
}) => {
  const formMethods = useFormContext()
  const { control } = formMethods ?? {}

  return (
    <Controller
      render={({ field }) => <DatePicker {...props} {...field} />}
      name={name ?? 'date'}
      control={control}
    />
  )
}

export default FormDateInput

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM