ReactJS - 向呈现的子组件添加事件侦听器(非虚拟DOM组件)

时间:2017-09-27 23:03:45

标签: javascript html reactjs

这个问题源于我尝试创建一个装饰器类型的组件,它通过包装它们并注入所需的样式和/或行为来为哑的表示组件添加功能。

以下是我想创建的“悬停装饰器”的示例:

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>

我的问题是上面的代码会将onMouseOveronMouseOut事件侦听器添加到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

1 个答案:

答案 0 :(得分:0)

您是否尝试在尝试添加事件侦听器的范围内使用ref标记?

<span 
ref={el => {this.decorator = el}} 
style={mergedStyle}>
  {this.state.children}
</span>

跟进问题:你为什么要克隆?常规渲染不能实现什么?

编辑:哇,很抱歉。我的意思是ref,而不是href