我经常发现自己处于需要使组件接受任何有效的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建议如何处理这个(非常常见的)用例。
是否有任何建议的方法以干净的方式处理此案件?
答案 0 :(得分:0)
除了你的方法,这主要是我见过的(但我只看过一些商店的风格),另外两种想法是:
单独提供一般属性:
<Input alert={...} general={{className: "foo"}} />
然后
return <input onChange={this.onChange} {...this.props.general} />;
我说:Blech。你使用Input
的地方很麻烦,并不能很好地构成......
给自己一个实用功能,你可以用来复制一个遗漏某些属性的对象,就像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