最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Hooks TypeScript event and state types - Stack Overflow

programmeradmin0浏览0评论

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
Add a ment  | 

3 Answers 3

Reset to default 3

I'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>
    );
}

发布评论

评论列表(0)

  1. 暂无评论