【发布时间】:2018-03-20 13:07:27
【问题描述】:
我们正在将用于特定触摸屏的现有应用程序迁移到 React。屏幕有一些敏感问题,所以我们想要自定义所有可点击组件(如按钮等)的onClick 行为。例如,如果用户按下按钮然后将手指移出,我们希望onClick 也触发放手前的按钮。
一般来说,我们需要为所有的可点击对象添加一些状态,我认为Higher Order Component 是最理想的,所以我做了以下操作:
HOC
const withTouchable = WrappedComponent => {
return class Touchable extends React.Component {
onClick() {
this.props.onClick();
}
onMouseLeave() {
// Some complicated logic to determine if we want to fire onClick
if(...) {
this.props.onClick();
}
}
// Other mouse and touch handlers
// onMouseMove = ...
render() {
return (
<WrappedComponent
{...this.props}
onClick={this.onClick.bind(this)}
onMouseLeave={this.onMouseLeave.bind(this)}
// other mouse and touch handlers
/>
);
}
};
};
我们希望可点击的示例组件。
const Heading = ({ title }) => <h1>{title}</h1>;
示例应用
const TouchableHeading = withTouchable(Heading);
class App extends React.Component {
onClick() {
console.log("title tapped")
}
render() {
return (
<TouchableHeading
title="Some title"
onClick={this.onClick.bind(this)}
/>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
不幸的是,这不起作用,因为虽然<WrappedComponent> 是通过鼠标和触摸处理程序返回的,但<Heading> 并没有使用它。见codepen.io/bvgZwb
另一种方法是在 WrapperComponent 周围包裹一个 div:
render() {
return (
<div
onClick={this.onClick.bind(this)}
onMouseLeave={this.onMouseLeave.bind(this)}
// other mouse and touch handlers
>
<WrappedComponent {...this.props}/>
</div>
);
}
见codepen.io/xWgBMJ。但这增加了一个额外的 DOM 元素,这并不理想(它与样式混淆,没有时间重写整个应用程序)。
还有其他我没有考虑过的方法来实现这一目标吗?我确实研究了render props and using functions as children,但我认为不可能以这种方式实现我的目标。
注意:不要介意this.onClick.bind(this)、I know。
【问题讨论】:
标签: javascript reactjs onclick higher-order-components