【问题标题】:Input Attribute onChange only if Props is not Undefined仅当 Props 未定义时输入属性 onChange
【发布时间】:2018-04-13 10:09:24
【问题描述】:

我将 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 告诉我“对象可能是'未定义'”,这是完全正确的,因为 this.props.inputOnChange 它是一个可选的道具。

所以,我想写的是“如果 this.props.inputOnChange(e) != undefined, 然后在输入中添加 onChange”,但是......我不知道该怎么做。

我试过条件渲染:

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

但它不起作用

编辑:我发现的一个解决方案是写这样的东西。

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

...

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

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

【问题讨论】:

  • onChange={ (e) => { if (this.props.inputOnChange) { this.props.inputOnChange(e) } } />
  • 完全没问题。
  • 我的代码?马丁

标签: javascript reactjs typescript


【解决方案1】:

通常,您将希望通过提供自己的函数来处理onChange,然后如果 prop 存在则有条件地传播。像这样的:

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 重新渲染整个子组件树,因为函数引用发生了变化。在这种情况下,这可能没什么大不了的,但如果您有大量的组件子树,您可能会相对较快地遇到性能问题。

【讨论】:

    【解决方案2】:

    你可以像这样包含条件道具。

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

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

    意思是,这都可以:

    <input   
      {...props} // you already know this spread syntax 
      {...props && props} // spreads if defined
      {...a && { a }} // shorthand property name
      {...c && { c: (e) => c(e) }}
      {...x && { x, y:2, z:3 }} // multiple properties
    />
    

    Shorthand property names (ES2015)

    【讨论】:

      【解决方案3】:

      你可以定义conditionalProps对象

      let conditionalProps = {}
      
      if (this.props.inputOnChange)
          conditionalProps["onChange"] = this.props.inputOnChange
      
      // or with custom fn
      if (this.props.inputOnChange)
          conditionalProps["onChange"] = (ev) => this.props.inputOnChange(ev, otherArgs)
      
      return <input { ...conditionalProps} />
      

      或者

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

      【讨论】:

      • 我觉得这个解决方案有点优雅,但是在 onChange 的情况下,我怎么能传递事件参数呢?或者如果需要更多参数?
      • 为此,您可以使用我在上面更新的替代选项。
      • @Jolly conditionalProps["onChange"] = (ev) =&gt; this.props.inputOnChange(ev, otherArgs)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      • 2016-11-23
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多