我们正在将针对特定触摸屏的现有应用程序迁移到 React。屏幕有一些灵敏度问题所以我们要自定义 onClick
所有可点击组件(如按钮等)的行为。例如,我们想要 onClick
如果用户按下按钮然后在松开之前将手指移出按钮,也会触发。
一般来说,我们需要为所有可点击对象添加一些状态,我想到了 Higher Order Component将是理想的选择,所以我做了以下内容:
高级组织
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 .
最佳答案
不使用包装器并做你想做的唯一方法是使用像这样的休息 Prop
const Heading = ({ title, ...rest }) => <h1 {...rest}>{title}</h1>;
然而,如果你对此不小心,你的所有属性都会到达你的 DOM,因为 React 在最新版本中不再进行属性验证
或
专门为Heading添加事件属性like
const Heading = ({ title, onClick, onMouseLeave }) => (
<h1
onClick={onClick}
onMouseLeave={onMouseLeave}
>
{title}
</h1>
)
关于javascript - 我可以使用高阶组件将 onClick 添加到我的组件而不添加包装器 DOM 元素吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49385060/