如何在 React with Typescript 中使用和指定通用 Hooks?
Posted
技术标签:
【中文标题】如何在 React with Typescript 中使用和指定通用 Hooks?【英文标题】:How to use and specify Generic Hooks in React with Typescript? 【发布时间】: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>>]
【问题讨论】:
【参考方案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<React.SetStateAction<T>>
更适合ResetFunction。更隐晦??你能纠正我吗??
如果你直接从钩子传递了setValue
,React.Dispatch<React.SetStateAction<T>>
将是一个正确的类型,但你不这样做,你创建一个不带参数并返回的新函数(reset)什么都没有,它会调用你的 setValue
函数,因此在我的示例中是 ResetFunction
的额外类型。
所以React.Dispatch
指定返回类型是可调用的,React.SetStateAction<T>
指定该特定可调用设置状态。我对吗??如果您有任何相关文档,请分享。谢谢!!
我刚刚完成了 React 的类型定义。调度类型:type Dispatch<A> = (value: A) => void;
:定义了一个泛型函数,它接受一个值并返回 void。 SetStateAction:type SetStateAction<S> = S | ((prevState: S) => S);
泛型类型,无论是泛型值本身还是获取参数并返回泛型类型的函数。所以Dispatch<SetStateAction<S>
基本上是一个函数,它获取单个值或一个函数(获取S
并返回S
)并返回void。以上是关于如何在 React with Typescript 中使用和指定通用 Hooks?的主要内容,如果未能解决你的问题,请参考以下文章
Typescript with React - 在通用组件类上使用 HOC
React Typescript with hooks:最大更新深度超出错误
Jest Manual Mocks with React 和 Typescript:模拟 ES6 类依赖