这个问题源于我尝试创建一个装饰器类型的组件,它通过包装它们并注入所需的样式和/或行为来为哑的表示组件添加功能。
以下是我想创建的“悬停装饰器”的示例:
class HoverDecorator extends React.Component {
constructor(props) {
super(props);
let defaultState = { hover: false };
this.state = Object.assign(defaultState, props);
}
handleMouseOver(event) {
console.log('Mouse Over');
this.setState({
hover: true
});
}
handleMouseOut(event) {
console.log('Mouse Out');
this.setState({
hover: false
});
}
render() {
let hoverStyle = {};
if (this.state.hover) { // Change the color if hovered.
hoverStyle = { color: '#FF0000' };
}
// Inject the new style and event handlers into the child component.
return React.cloneElement(
React.Children.only(this.state.children), // Only allows a single child.
{
style: hoverStyle,
onMouseOver: this.handleMouseOver.bind(this),
onMouseOut: this.handleMouseOut.bind(this)
}
);
}
}
可以在这样的虚拟组件上使用:
class DummyTextBox extends React.Component {
constructor(props) {
super(props);
this.state = props;
}
render() {
let boxStyle = { color: '#0000FF' };
// Overwrite the default boxStyle with any styles passed in via props.
let mergedStyle = Object.assign(boxStyle, this.state.style);
return (<span style={mergedStyle}>{this.state.children}</span>);
}
}
用于创建和包装DummyTextBox
的JSX看起来像:
<HoverDecorator>
<DummyTextBox>Lorem Ipsum</DummyTextBox>
</HoverDecorator>
我的问题是上面的代码会将onMouseOver
和onMouseOut
事件侦听器添加到DummyTextBox
虚拟DOM元素,而不是它呈现的实际span
。当我通过chrome扩展检查React DOM时,我看到以下内容:
<HoverDecorator>
<DummyTextBox style={} onMouseOver=bound handleMouseOver() onMouseOut=bound handleMouseOut()>
<span style={color: "#0000FF"}>Lorem Ipsum</span>
</DummyTextBox>
</HoverDecorator>
这当然不起作用,因为DummyTextBox
本身只是一个虚拟DOM元素。有没有办法可以将事件监听器添加到<span>
的{{1}}方法返回的DummyTextBox
?
答案 0 :(得分:0)
您是否尝试在尝试添加事件侦听器的范围内使用ref
标记?
<span
ref={el => {this.decorator = el}}
style={mergedStyle}>
{this.state.children}
</span>
跟进问题:你为什么要克隆?常规渲染不能实现什么?
编辑:哇,很抱歉。我的意思是ref
,而不是href
。