![](/img/trans.png)
[英]React Hooks TypeScript inheriting parent state & function types in child
[英]React Hooks TypeScript event and state types
React.js 的状态和事件有哪些类型?
在我下面的代码中,我只能通过使用type: any
使其工作,但这只是一个 hack。 我怎样才能为他们使用正确的类型?
在我的自定义钩子中:
如果我使用function useFormFields(initialState: object)
,我会得到:
// value={inputs.item} error:
Property 'item' does not exist on type 'object'.ts(2339)
// onChange function error:
(JSX attribute) onChange: object
No overload matches this call.
如果我使用function(event: React.FormEvent)
(这是真的),我有这个错误:
Property 'id' does not exist on type 'EventTarget'.ts(2339)
如果我使用function(event: object)
,则会出现此错误:
Property 'target' does not exist on type 'object'.ts(2339)
这很奇怪,因为下面我使用const handleSubmitItem = (event: React.FormEvent)
并且它有效。
我找到的答案(比如这个)对我不起作用,因为Property 'id' does not exist on type 'EventTarget'
import React, {useState} from 'react';
import TextField from '@material-ui/core/TextField';
import IconButton from '@material-ui/core/IconButton';
import AddShoppingCartIcon from '@material-ui/icons/AddShoppingCart';
/**
* Custom hooks for input fields.
* @param initialState initialState for Input Fields
*/
function useFormFields(initialState: any) {
const [inputs, setValues] = useState(initialState);
return [
inputs,
function(event: any) {
setValues({
...inputs,
[event.target.id]: event.target.value
});
}
];
}
export default function FormPropsTextFields() {
const [inputs, handleInputChange] = useFormFields({
item: '',
quantity: '',
store: ''
});
const handleSubmitItem = (event: React.FormEvent) => {
event.preventDefault();
console.log(inputs);
};
return (
<form
className={classes.root}
noValidate autoComplete="off"
onSubmit={handleSubmitItem}
>
<div>
<TextField
required id="item"
label="Item"
value={inputs.item}
onChange={handleInputChange}
/>
<TextField
id="quantity"
label="Quantity"
type="number"
value={inputs.quantity}
onChange={handleInputChange}
InputLabelProps={{
shrink: true,
}}
/>
<TextField
id="store"
label="Store"
type="search"
value={inputs.store}
onChange={handleInputChange}
/>
<IconButton
type="submit"
color="primary"
aria-label="add to shopping cart"
>
<AddShoppingCartIcon />
</IconButton>
</div>
</form>
);
}
我在您找到的解决方案中进行了一些更正。 希望能帮助到你!
import React, {useState} from 'react';
import TextField from '@material-ui/core/TextField';
import IconButton from '@material-ui/core/IconButton';
import AddShoppingCartIcon from '@material-ui/icons/AddShoppingCart';
/**
* Custom hooks for input fields.
* @param initialState initialState for Input Fields
*/
export interface MyModel {
item: string
quantity: string
store: string
}
function useFormFields<T>(initialState: T): [T, (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => void] {
const [inputs, setValues] = useState<T>(initialState);
return [
inputs,
function (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) {
setValues({
...inputs,
[event.target.id]: event.target.value
});
}
];
}
export default function FormPropsTextFields() {
const [inputs, handleInputChange] = useFormFields<MyModel>({
item: '',
quantity: '',
store: ''
});
const handleSubmitItem = (event: React.FormEvent) => {
event.preventDefault();
console.log(inputs);
};
return (
<form
className={classes.root}
noValidate autoComplete="off"
onSubmit={handleSubmitItem}
>
<div>
<TextField
required id="item"
label="Item"
value={inputs.item}
onChange={handleInputChange}
/>
<TextField
id="quantity"
label="Quantity"
type="number"
value={inputs.quantity}
onChange={handleInputChange}
InputLabelProps={{
shrink: true,
}}
/>
<TextField
id="store"
label="Store"
type="search"
value={inputs.store}
onChange={handleInputChange}
/>
<IconButton
type="submit"
color="primary"
aria-label="add to shopping cart"
>
<AddShoppingCartIcon />
</IconButton>
</div>
</form>
);
}
由于每个组件可能不同,您需要自己定义 state 和 props 类型。 有一些为 react 定义的基本类型(例如,因为每个组件都可能有children
组件),但正如我所说,您需要定义自己的类型。
功能组件的示例:
const App: React.FC<{ message: string }> = ({ message }) => (
<div>{message}</div>
);
上面的例子也可以这样写:
type MyType = { message: string }
const App: React.FC<MyType> = ({ message }) => (
<div>{message}</div>
);
进一步阅读:
https://github.com/typescript-cheatsheets/react-typescript-cheatsheet#section-2-getting-started
将军们! 答案!
希望能帮助到你!
import IconButton from '@material-ui/core/IconButton';
import TextField from '@material-ui/core/TextField';
import AddShoppingCartIcon from '@material-ui/icons/AddShoppingCart';
import React, { useState } from 'react';
export interface MyModel {
item: string;
quantity: string;
store: string;
}
/**
* Custom hooks for input fields.
* @param initialState initialState for Input Fields
**/
function useFormFields<T>(initialState: T) {
const [inputs, setValues] = useState(initialState);
return [
inputs,
function(event: React.FormEvent) {
const {name, value} = event.currentTarget;
setValues({
...inputs,
[name]: value
});
}
];
}
export default function FormPropsTextFields() {
const [inputs, handleInputChange] = useFormFields<MyModel>({
item: '',
quantity: '',
store: '',
});
const handleSubmitItem = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
/***
make sure to have whatever attribute you want in the "html tag"
*/
const { name, value } = event.currentTarget;
console.log(inputs);
};
return (
<form
className={classes.root}
noValidate autoComplete="off"
>
<div>
<TextField
required id="item"
label="Item"
name="Item"
value={inputs.item}
onChange={handleInputChange}
/>
<TextField
id="quantity"
label="Quantity"
name="Quantity"
type="number"
value={inputs.quantity}
onChange={handleInputChange}
InputLabelProps={{
shrink: true,
}}
/>
<TextField
id="store"
label="Store"
name="Store"
type="search"
value={inputs.store}
onChange={handleInputChange}
/>
<IconButton
type="button"
color="primary"
aria-label="add to shopping cart"
onClick={handleSubmitItem}
>
<AddShoppingCartIcon />
</IconButton>
</div>
</form>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.