我是 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 website 中的示例。但是,由于 TypeScript 的“打字”,以下内容在我的 .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: 字符串]: 字符串; }' 不可分配给类型“Pick”

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

这可能很简单,但是如何在 TypeScript 中实现这一点?

谢谢。

请您参考如下方法:

此错误有点难以跟踪,但这并不是因为您所在的州不存在该名称。这是因为您的状态属性未标记为可选。因此:

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

allow typescript compiler to call setState on only one react state property


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!