在 React 钩子中,handleChange 中没有 e.target 和 setValue()

Jai*_*zar 0 javascript forms reactjs react-hooks

由于我正在学习如何使用钩子构建 React 表单,因此我浏览了 3 篇以这篇文章告终的快报。一切都很顺利,直到我进入最后一步,当您使用以下命令创建自定义挂钩时:

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

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

  return {
    value,
    onChange: handleChange
  };
}
Run Code Online (Sandbox Code Playgroud)

输入是:

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

表格是:

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

所以在useFormInput()Chrome 中抱怨

类型错误:无法在 handleChange 读取未定义的属性“值”

我很确定这是指向我的

function handleChange(e) {
  setValue(e.target.value);
}
Run Code Online (Sandbox Code Playgroud)

如果我 console.log(e) 我会收到“电子邮件”,正如预期的那样(我认为?),但如果我尝试 console.log(e.target) 我得到未定义。所以显然 e.target.value 不存在。我可以通过使用来让它工作

setValue(document.getElementsByName(e)[0].value);
Run Code Online (Sandbox Code Playgroud)

但我不知道这可能有什么样的问题。这是一个好主意吗?让它以这种方式工作有什么缺点吗?

谢谢

Moh*_*ami 5

问题来自组件中的onChange道具Input

    onChange={event => {
        event.preventDefault();
        onChange(name, event.target.value);
    }}
Run Code Online (Sandbox Code Playgroud)

onChange像这样调用onChange(name, event.target.value); (两个参数,第一个是字符串),而在您的自定义钩子中,您可以像这样定义回调

  function handleChange(e) {
    setValue(e.target.value);
  }
Run Code Online (Sandbox Code Playgroud)

它期待一个参数,一个事件。

因此,要么onChange使用一个参数(事件)调用:

onChange={event => {
    event.preventDefault();
    onChange(event);
}}
Run Code Online (Sandbox Code Playgroud)

或更改回调的实现。