正确避免将无效属性传递给React原语

时间:2017-04-23 12:34:03

标签: javascript reactjs

我经常发现自己处于需要使组件接受任何有效的HTML属性以使基础HTML元素使用它们的情况。

class Input extends React.Component {
  // Here I use one of the `props` to add logic to
  // my component
  onChange = () => alert(this.props.alert);

  render() {
    // Here I want to pass all the properties
    // down to the HTML input element
    return <input onChange={this.onChange} {...this.props} />
  }
}

我的上述示例将发出警告,因为React抱怨alert属性不是input的有效属性。

我通常按如下方式解决问题:

class Input extends React.Component {
  // Here I use one of the `props` to add logic to
  // my component
  onChange = () => alert(this.props.alert);

  render() {
    const {
      alert, // eslint-disable-line no-unused-vars
      ...props
    } = this.props;

    // Here I want to pass all the properties
    // down to the HTML input element
    return <input onChange={this.onChange} {...props} />
  }
}

现在组件工作正常,但我对最终结果感到不舒服。

我理解为什么React不允许将未知属性传递给它的原语,因为它们不会使用它们而且提供无用属性并不是很干净,以后可能会成为有效的HTML属性或导致不良行为或方面效果。
但我不明白React建议如何处理这个(非常常见的)用例。

是否有任何建议的方法以干净的方式处理此案件?

2 个答案:

答案 0 :(得分:0)

除了你的方法,这主要是我见过的(但我只看过一些商店的风格),另外两种想法是:

  1. 单独提供一般属性:

    <Input alert={...} general={{className: "foo"}} />
    

    然后

    return <input onChange={this.onChange} {...this.props.general} />;
    

    我说:Blech。你使用Input的地方很麻烦,并不能很好地构成......

  2. 给自己一个实用功能,你可以用来复制一个遗漏某些属性的对象,就像Underscore / Lodash的_.omit

    const objectExcept(obj, ...except) {
        const result = {};
        Object.keys(obj).forEach(key => {
            if (!except.includes(key)) {
                result[key] = obj[key];
            }
        });
        return result;
    };
    

    然后

    return <input onChange={this.onChange} {...objectExcept(this.props, "alert")} />;
    

    objectExcept版本采用离散参数,但你可以让它接受一个数组,一个分隔的字符串,对你有用的东西......

答案 1 :(得分:-1)

也许我误解了,但为了排除某些道具,你不能只使用解构吗?

  render() {
    const {foo, bar} = this.props;
    const inputProps = {foo, bar}

    return <input onChange={this.onChange} {...inputProps} />
  }

然后你可以在Input类的其他地方使用this.props.alert。

甚至,如果你使用带有babel的点差:

const {alert, ...inputProps} = this.props

这将忽略来自新inputProps对象的警报。更多信息:clone a js object except for one key