我可以使用更高阶的组件将 onClick 添加到我的组件而不添加包装器 DOM 元素吗?



我们正在将特定触摸屏的现有应用程序移动到 React。屏幕有一些灵敏度问题,因此我们希望自定义所有可点击组件(如按钮等)的onClick行为。例如,我们希望如果用户按下按钮,然后在松开按钮之前将手指移出按钮,则onClick也会触发。

一般来说,我们需要为所有可点击量添加一些状态,我认为高阶组件是理想的选择,所以我做了以下工作:

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

另一种方法是在包装组件周围包装一个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 元素,这并不理想(它弄乱了样式,没有时间重写整个应用程序)。

有没有另一种我没有考虑过的方法来实现这一点?我确实在孩提时代研究过渲染道具和使用功能,但我认为以这种方式不可能实现我的目标。

注意:不介意this.onClick.bind(this),我知道。

不使用包装器并做你想做的事的唯一方法是使用休息道具,例如

const Heading = ({ title, ...rest }) => <h1 {...rest}>{title}</h1>;

但是,如果您不小心,您的所有属性都将到达您的 DOM,因为 React 不再在最新版本中进行属性验证

专门将事件属性添加到标题中,例如

const Heading = ({ title, onClick, onMouseLeave }) => (
<h1 
onClick={onClick}
onMouseLeave={onMouseLeave}
>
{title}
</h1>
)

相关内容

  • 没有找到相关文章

最新更新