繁体   English   中英

带React.JS的打字稿-处理多个输入的表单事件

[英]Typescript with React.JS - Handling Form Events for Multiple Inputs

我是React.js的新手,但是正在尝试使用TypeScript / TSX组合一个简单的应用程序。 该应用程序包含需要验证的表单。 我通过为每个输入分配处理程序并相应地更新状态来使其工作,但这有点麻烦(即使对于我正在创建的小型表单):

export interface AddInventoryRowProps {
    catOptions : Array<any>,
    conditionOptions: Array<any>
}

export interface AddInventoryState {
    title: string,
    sku: string,
    mpn: string,
    catID : string,
    conditionID: string,
    price: string,
    isCategoryValid : boolean,
    isMPNValid : boolean,
    isSKUValid : boolean,
    isTitleValid : boolean,
    isPriceValid : boolean,
    isConditionValid : boolean

}

export class AddInventoryRow extends React.Component<AddInventoryRowProps, AddInventoryState> {
    constructor(props : AddInventoryRowProps) {
        super(props);
        this.state = { title: "", 
        sku: "", 
        mpn: "", 
        catID: "",
        price: "", 
        conditionID: "",
        isCategoryValid: false,
        isMPNValid: false,
        isPriceValid: false,
        isSKUValid: false,
        isTitleValid: false,
        isConditionValid: false}

        this.handleCatChange = this.handleCatChange.bind(this);
        this.handleConditionChange = this.handleConditionChange.bind(this);
        this.handlePriceChange = this.handlePriceChange.bind(this);
        this.handleSKUChange = this.handleSKUChange.bind(this);
        this.handleSubmitClick = this.handleSubmitClick.bind(this);
        this.handleMPNChange = this.handleMPNChange.bind(this);
       this.handleTitleChange = this.handleTitleChange.bind(this);
    }

每个“句柄”函数都将如下所示:

    handleMPNChange(ev : ChangeEvent<HTMLInputElement>) {
    this.setState( {isMPNValid: (ev.currentTarget as HTMLInputElement).value != "" });
    this.setState( {mpn: (ev.currentTarget as HTMLInputElement).value });
}

render()函数中具有相应的输入元素:

   <div className="form-group">
   <label>UPC/MPN</label>
   <input name="mpn" onChange={this.handleMPNChange} value={this.state.mpn} id="mpn" 
 className={this.state.isMPNValid ? "form-control form-control-sm" 
 : "form-control form-control-sm error is-invalid" } />
   </div>

我想制作一个输入处理程序,类似于React网站上的示例。 但是,由于TypeScripts的“键入”,以下内容在我的.txs文件中不起作用:

handleChange(ev : ChangeEvent<HTMLInputElement>) {
    const target : HTMLInputElement = ev.currentTarget as HTMLInputElement;
            const name : string = target.name;
            const value: string = target.value;
            this.setState( {[name]: value});
}

详细地说,它给出以下错误:

     Argument of type '{ [x: string]: string; }' is not assignable to parameter of type 'AddInventoryState | ((prevState: Readonly<AddInventoryState>, props: AddInventoryRowProps) => Add...'.

类型'{[x:string]:string; }'不能分配给'Pick类型

从名称中删除[]会产生类似的错误。 现在我知道我可以通过在创建类时简单地指定any的类型而不是AddInventoryState来解决此问题,但这似乎不是一个正确的解决方法。

这可能很简单,但是在TypeScript中如何解决呢?

谢谢。

this.setState( {[name]: value}); 名称在您的州不存在。

更改为此:

 this.setState(() => ({ mpn: value, }));

如果this.state.mpnthis.state.mpn应该包含您输入的值。

很难跟踪此错误,但这不是由于名称在您的州不存在。 这是由于您的状态属性未标记为可选的。 Ergo:

export interface AddInventoryState {
    title?: string,
    ...
}

因此, setState希望您像在构造函数中一样设置所有属性。 幸运的是,已添加了映射类型,因此您只需将状态标记为Partial即可使其工作:

export class AddInventoryRow extends React.Component<AddInventoryRowProps, Partial<AddInventoryState>>

给出React 16.4的定义,

// We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
// See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
// Also, the ` | S` allows intellisense to not be dumbisense
setState<K extends keyof S>(
    state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
    callback?: () => void
): void;

您也可以像这样设置状态, AddInventoryState标记为Partial

this.setState((current) => ({ ...current, [name]: value }))

更多信息:

https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types

https://reactjs.org/docs/forms.html#handling-multiple-inputs

允许打字稿编译器仅在一个反应​​状态属性上调用setState

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM