React Custom Hook with Typescript Type 错误“属性 'x' 不存在于类型 'interface | (({ target }: any) => void)'.ts(2339)”

use*_*992 5 typescript reactjs react-hooks

我正在尝试使用自定义钩子管理表单,所以我有这个代码

FormHook.tsx:

import { useState } from 'react';

interface ICampos  {
    name: string;
    email: string;
    password: string;
}


const useForm = (initialState: ICampos) => {
    
    const [values, setValues] = useState(initialState);


    const handleInputChange = ({ target }: any) => {
        setValues({
            ...values,
            [target.name]: target.value
        })
    };

    return [values, handleInputChange];
}

export default useForm
Run Code Online (Sandbox Code Playgroud)

FormWithCustomHook.tsx:

import React from 'react'
import './effects.css' 
import useForm from '../../hooks/useForm';

interface ICampos  {
    name: string;
    email: string;
    password: string;
}

const FormWithCustomHook = () => {

    const [formValues, handleInputChange] = useForm({
        name: '',
        email: '',
        password: ''
    });

    const { name, email, password } = formValues;



    return (
        <>
            <h1> FormWithCustomHook </h1>
            <hr />

            <div className="form-group">
                <input
                    type="text"
                    name="name"
                    className="form-control"
                    placeholder="Tu nombre"
                    autoComplete="off"
                    value={name}
                    onChange={handleInputChange} />
            </div>
            
            <div className="form-group">

                <input
                    type="email"
                    name="email"
                    className="form-control"
                    placeholder="email@ejemplo.com"
                    autoComplete="off"
                    value={email}
                    onChange={handleInputChange} />
            </div>

            <div className="form-group">

                <input
                    type="password"
                    name="password"
                    className="form-control"
                    placeholder="*****"
                    autoComplete="off"
                    value={password}
                    onChange={handleInputChange} />
            </div>

        </>
    )
}

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

我在 FormWithCustomHook.tsx 上遇到了这个错误:

const { name, email, password } = formValues;
Run Code Online (Sandbox Code Playgroud)

它仅在电子邮件和密码上标记错误:

'ICampos | 类型不存在'属性'电子邮件' (({ target }: any) => void)'.ts(2339)'

在我的 onChange 输入中说:

输入'ICampos | (({ target }: any) => void)' 不可分配给类型 '((event: ChangeEvent) => void) | 不明确的'。类型 'ICampos' 不可分配给类型 '(event: ChangeEvent) => void'。类型“ICampos”不匹配签名“(event: ChangeEvent): void”.ts(2322) index.d.ts(2092, 9):预期的类型来自属性“onChange”,它在类型上声明'DetailedHTMLProps<InputHTMLAttributes, HTMLInputElement>''

我试图在 customhook.tsx 上添加类型,但我真的不明白这个错误

Fed*_*cci 4

钩子不知道数组的顺序。所以可能是ICampos | HandlerHandler | ICampos。您在这里有两个选择:

您可以在钩子上键入返回数组:

const useForm = (
  initialState: ICampos
): [ICampos, ({ target }: any) => void] => {
  const [values, setValues] = useState<ICampos>(initialState);

  const handleInputChange = ({ target }: any) => {
    setValues({
      ...values,
      [target.name]: target.value
    });
  };

  return [values, handleInputChange];
};
Run Code Online (Sandbox Code Playgroud)

或者您可以返回一个对象而不是数组。我更喜欢这个,因为我不喜欢输入数组。

import { useState } from "react";

interface ICampos {
  name: string;
  email: string;
  password: string;
}

const useForm = (initialState: ICampos) => {
  const [values, setValues] = useState<ICampos>(initialState);

  const handleInputChange = ({ target }: any) => {
    setValues({
      ...values,
      [target.name]: target.value
    });
  };

  return { values, handleInputChange };
};

export default useForm;
Run Code Online (Sandbox Code Playgroud)
import React from "react";
import "./effects.css";
import useForm from "./useForm";

interface ICampos {
  name: string;
  email: string;
  password: string;
}

const FormWithCustomHook = () => {
  const { values, handleInputChange } = useForm({
    name: "",
    email: "",
    password: ""
  });

  const { name, email, password } = values;

  return (
    <>
      <h1> FormWithCustomHook </h1>
      <hr />

      <div className="form-group">
        <input
          type="text"
          name="name"
          className="form-control"
          placeholder="Tu nombre"
          autoComplete="off"
          value={name}
          onChange={handleInputChange}
        />
      </div>

      <div className="form-group">
        <input
          type="email"
          name="email"
          className="form-control"
          placeholder="email@ejemplo.com"
          autoComplete="off"
          value={email}
          onChange={handleInputChange}
        />
      </div>

      <div className="form-group">
        <input
          type="password"
          name="password"
          className="form-control"
          placeholder="*****"
          autoComplete="off"
          value={password}
          onChange={handleInputChange}
        />
      </div>
    </>
  );
};

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