【问题标题】:How to use and specify Generic Hooks in React with Typescript?如何在 React with Typescript 中使用和指定通用 Hooks?
【发布时间】:2021-03-20 16:08:01
【问题描述】:

我正在尝试创建一个通用挂钩来处理按钮输入元素,它返回输入值数组、绑定对象和重置处理程序。

组件

import React, { useState } from "react";
import { useInput } from "../services/FormInputHooks";

export type AddTransactionProps = {};

export const AddTransaction: React.FC<AddTransactionProps> = () => {
    const [text, bindText, resetText] = useInput<string>("");
    const [amount, bindAmount, resetAmount] = useInput<number>(0.0);

    return (
        <>
            <h3>Add new transaction</h3>
            <form>
                <div className="form-control">
                    <label htmlFor="text">Text</label>
                    <input
                        type="text"
                        {...bindText}
                        placeholder="Enter text.."
                    />
                </div>
                <div className="form-control">
                    <label htmlFor="amount">
                        Amount <br />
                        (negative - expense, positive - income)
                    </label>
                    <input
                        type="number"
                        {...bindAmount}
                        placeholder="Enter amount.."
                    />
                </div>
                <button className="btn"> Add Transaction</button>
            </form>
        </>
    );
};

export default AddTransaction;

挂钩

import { useState } from "react";

export function useInput<T>(
    initialValue: T
): [T, any, React.Dispatch<React.SetStateAction<T>>] {
    const [value, setValue] = useState<T>(initialValue);

    const reset = () => {
        setValue(initialValue);
    };

    const bind = {
        value,
        onChange: e => {
            setValue(e.target.value);
        }
    };

    return [value, bind, reset];
}

我面临的问题

Parameter 'e' implicitly has an 'any' type.  TS7006

    12 |     const bind = {
    13 |         value,
  > 14 |         onChange: e => {
       |                   ^
    15 |             setValue(e.target.value);
    16 |         }
    17 |     };

虽然我已经为绑定对象指定了 any 的类型,但它显示了上述错误。我什至尝试使用以下代码来指定返回类型。

[T, {T: onChange: (e: any) => void}, React.Dispatch<React.SetStateAction<T>>]

【问题讨论】:

    标签: reactjs typescript react-hooks typescript-generics


    【解决方案1】:
    import React, { useState } from "react";
    
    export function useInput<T>(
        initialValue: T
    ): [T, any, React.Dispatch<React.SetStateAction<T>>] {
        const [value, setValue] = useState<T>(initialValue);
    
        const reset = () => {
            setValue(initialValue);
        };
    
        const bind = {
            value,
            onChange: (e: React.ChangeEvent<any>) => {
                setValue(e.target?.value);
            }
        };
    
        return [value, bind, reset];
    }
    

    Playground

    【讨论】:

      【解决方案2】:

      问题不是你为钩子返回值定义的类型,而是绑定对象没有任何类型注释,所以它的onChange方法的e参数将隐含为any。

      修复其类型注释的一种可能解决方案:

      import { useState, ChangeEventHandler } from "react";
      
      interface ResetFunction {
          (): void
      }
      
      interface Bind<T> {
        value: T,
        onChange: ChangeEventHandler<any>
      }
      
      export function useInput<T>(
          initialValue: T
      ): [T, Bind<T>, ResetFunction] {
          const [value, setValue] = useState<T>(initialValue);
      
          const reset = () => {
              setValue(initialValue);
          };
      
          const bind: Bind<T> = {
              value,
              onChange: e => {
                  setValue(e.target.value);
              }
          };
      
          return [value, bind, reset];
      }
      

      Typescipt playground

      【讨论】:

      • 我认为React.Dispatch&lt;React.SetStateAction&lt;T&gt;&gt; 更适合ResetFunction。更隐晦??你能纠正我吗??
      • 如果你直接从钩子传递了setValueReact.Dispatch&lt;React.SetStateAction&lt;T&gt;&gt; 将是一个正确的类型,但你不这样做,你创建一个不带参数并返回的新函数(reset)什么都没有,它会调用你的 setValue 函数,因此在我的示例中是 ResetFunction 的额外类型。
      • 所以React.Dispatch 指定返回类型是可调用的,React.SetStateAction&lt;T&gt; 指定该特定可调用设置状态。我对吗??如果您有任何相关文档,请分享。谢谢!!
      • 我刚刚完成了 React 的类型定义。调度类型:type Dispatch&lt;A&gt; = (value: A) =&gt; void;:定义了一个泛型函数,它接受一个值并返回 void。 SetStateAction:type SetStateAction&lt;S&gt; = S | ((prevState: S) =&gt; S); 泛型类型,无论是泛型值本身还是获取参数并返回泛型类型的函数。所以Dispatch&lt;SetStateAction&lt;S&gt; 基本上是一个函数,它获取单个值或一个函数(获取S 并返回S)并返回void。
      猜你喜欢
      • 2020-08-10
      • 2020-07-10
      • 1970-01-01
      • 2021-12-27
      • 2023-01-09
      • 2020-04-09
      • 2019-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多