What are the types of React.js's state and event?
In my code below, I can only make it work by using type: any
but it's just a hack. How can I use the right types for them?
In my custom hooks:
If I use function useFormFields(initialState: object)
, I get:
// 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.
If I use function(event: React.FormEvent)
(which is true), I have this error:
Property 'id' does not exist on type 'EventTarget'.ts(2339)
If I use function(event: object)
, I have this error:
Property 'target' does not exist on type 'object'.ts(2339)
That's odd because below I use const handleSubmitItem = (event: React.FormEvent)
and it works.
The answers I've found (like this one) don't work for me because 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>
);
}
What are the types of React.js's state and event?
In my code below, I can only make it work by using type: any
but it's just a hack. How can I use the right types for them?
In my custom hooks:
If I use function useFormFields(initialState: object)
, I get:
// 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.
If I use function(event: React.FormEvent)
(which is true), I have this error:
Property 'id' does not exist on type 'EventTarget'.ts(2339)
If I use function(event: object)
, I have this error:
Property 'target' does not exist on type 'object'.ts(2339)
That's odd because below I use const handleSubmitItem = (event: React.FormEvent)
and it works.
The answers I've found (like this one) don't work for me because 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>
);
}
Share
Improve this question
edited Feb 9, 2020 at 16:17
Ed Lucas
7,3654 gold badges40 silver badges50 bronze badges
asked Feb 9, 2020 at 14:34
VietViet
6,96315 gold badges47 silver badges79 bronze badges
3 Answers
Reset to default 3I've made some corrections in the solution that you found. Hope it helps!
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>
);
}
Since every ponent may be different you need to define the state and props types by yourself. There are some basic types defined for react (because every ponent may have children
for example) but as i said, you will need to define your own types.
An example for a functional ponent:
const App: React.FC<{ message: string }> = ({ message }) => (
<div>{message}</div>
);
The example above could also be written like so:
type MyType = { message: string }
const App: React.FC<MyType> = ({ message }) => (
<div>{message}</div>
);
further reading here:
https://github./typescript-cheatsheets/react-typescript-cheatsheet#section-2-getting-started
Generals! the answer!
hope it helps!
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>
);
}