React是否可以将所有事件传递给子元素。
作为一个例子我有一个自定义Button类,(简化)看起来像这样:
class Button extends Component {
constructor (props) {
super(props);
this.onClick = this.onClick.bind(this);
}
/* .... */
onClick (ev) {
const { disabled, onClick } = this.props;
if (!disabled) {
onClick(ev);
}
}
render () {
const {
children,
disabled,
type
} = this.props;
return (
<button
disabled={disabled}
onClick={this.onClick}
ref="button"
type={type}
>{children}</button>
}
}
我不知道将来我想要使用哪些事件(onMouseDown,onMouseUp,onBlur,onKeyDown,onTouchStart等等)
是否可以将所有可能的事件传递给按钮元素,而无需为每个可能的事件写出道具?
将<... this.props}添加到按钮元素不是我想要的,因为它传递了所有道具,并且不应直接传递一些道具(如本例中省略的className)。
我想克隆道具对象并删除不应该直接传递的道具,但这感觉就像一个黑客。有人知道更干净的方式吗?
答案 0 :(得分:2)
我编写了一个迭代道具的函数,并过滤掉所有以'on'开头的属性,这是我到目前为止最接近的。万一它可以帮助其他人:
/* helpers.js */
export function filterEvents (props, ignore = []) {
let events = {};
for (let property in props) {
if (props.hasOwnProperty(property)) {
if (property.startsWith('on') && ignore.indexOf(property) === -1) {
events[property] = props[property];
}
}
}
return events;
}
/* Tests for the filterEvents */
import { expect } from 'chai';
import { filterEvents } from './helpers';
describe('filterEvents', () => {
const props = {
className: 'someClass',
disabled: true,
onBlur: 'onBlur',
onClick: 'onClick',
onMouseDown: 'onMouseDown',
onMouseUp: 'onMouseUp'
};
it('only returns keys starting with on', () => {
const expected = {
onBlur: 'onBlur',
onClick: 'onClick',
onMouseDown: 'onMouseDown',
onMouseUp: 'onMouseUp'
};
expect(filterEvents(props)).to.deep.equal(expected);
});
it('only returns keys starting with on minus the ones in the ignore array', () => {
const expected = {
onBlur: 'onBlur',
onMouseUp: 'onMouseUp'
};
const ignore = ['onClick', 'onMouseDown'];
expect(filterEvents(props, ignore)).to.deep.equal(expected);
});
});
/* Using the function inside a component */
import { filterEvents } from './helpers'; //at the top of the components file
//Inside the render method:
const events = filterEvents(this.props, ['onClick']); //don't include onClick it's handled like the questions example
return (
<button
disabled={this.props.disabled}
onClick={this.onClick}
{...events}
>
{this.props.children}
</button>
);