仅当Props不是Undefined时,输入属性onChange

时间:2018-04-13 10:09:25

标签: javascript reactjs typescript

我正在使用React和TypeScript,并且我已经创建了一个输入组件,它将占用大量的道具,其中许多是可选的。到目前为止,我已经这样了。

interface InputProps {
    labelClassName?: string;
    labelName?: string;
    inputType: string;
    inputName?: string;
    inputValue: any;
    inputOnChange?: (e: any) => void;
    readOnly?: boolean;
}

现在,在输入组件中,我想渲染一个带有输入的标签标签。这个输入将基本上继承所有的道具,所以我会有这样的东西。

export class Input extends React.Component<InputProps, {}> {
render() {
    console.log(this.props); 
    return (
        <label className={this.props.labelClassName}>
            {this.props.labelName}
            <input
                type={this.props.inputType}
                name={this.props.inputName}
                value={this.props.inputValue || ""}
                readOnly={this.props.readOnly}
                onChange={(e) => this.props.inputOnChange(e)} />
        </label>)
        ;
    }
}

现在,问题在于我无法用OnChange写行,因为TypeScript告诉我&#34;对象可能是未定义的&#39;&#34;,这是完全正确的,因为this.props.inputOnChange它是一个可选的道具。

所以,我想写的是&#34;如果this.props.inputOnChange(e)!= undefined,那么在输入中添加onChange&#34;,但是。 ..我不知道这是怎么回事。

我已尝试过条件渲染:

{this.props.inputOnChange &&
                onChange = {(e) => this.props.inputOnChange(e)} />

但它不起作用

编辑:我找到了一个解决方案就是写这样的东西。

let inputOnChange = (this.props.inputOnChange != undefined)
        ? this.props.inputOnChange
        : undefined;

...

<input
    ...
    onChange={inputOnchange} />

但老实说,我不知道将未定义传递给onChange是否可以

3 个答案:

答案 0 :(得分:1)

通常,您需要通过提供自己的函数来处理onChange,然后在道具存在的情况下有条件地传播。像这样:

export class Input extends React.Component<InputProps, {}> {

    handleOnChange = (e) => {
        if (this.props.inputOnChange) {
            this.props.inputOnChange(e);
        }
    }

    render() {
        console.log(this.props);
        const { labelClassName, labelName, inputType, inputName, 
                inputValue, readOnly } = this.props;

        return (
            <label className={labelClassName}>
                {labelName}
                <input
                    type={inputType}
                    name={inputName}
                    value={inputValue || ""}
                    readOnly={readOnly}
                    onChange={this.handleOnChange} />
            </label>
        );
    }
}

我会给你一个额外的建议,如果你能提供帮助,不要在render方法中创建箭头功能。例如:

<input onChange={(e) => something} />

每次调用render方法时,上面都会创建一个新函数。这将导致react重新呈现整个子组件树,因为函数引用已更改。在这种情况下,它可能不是什么大问题,但如果你有一个很大的组件子树,你可以相对快速地遇到性能问题。

答案 1 :(得分:0)

您可以定义conditionalProps对象

let conditionalProps = {}
if (this.props.inputOnChange)
    conditionalProps["onChange"] = this.props.inputOnChange

    <input { ...conditionalProps} />

替代

  {this.props.inputOnChange ? <input onChange= {(e)=>this.props.inputOnchange(e)}  /> : <input />}

答案 2 :(得分:0)

您可以包括这样的条件道具。

<input    
  {...this.props.inputOnChange && { onChange: (e) => this.props.inputOnChange(e) }}
/>

根据需要重复许多道具。这只是使用Spread Attributes syntax,并且您不仅限于对象中的一种价差或一种属性。

意思是,一切正常:

<input    
  {...a && { a }} // shorthand property name
  {...c && { c: () => c() }}
  {...x && { x:1, y:2, z:3 }} // multiple properties
/>

Shorthand property names (ES2015)