event.stopPropagation()在本机HTMLElement内的ReactJS组件上失败

时间:2019-04-12 20:40:28

标签: javascript reactjs

因此,我对React的特殊使用情况是:

我希望为页面上的所有卡片添加一个小的React组件到卡片上,该卡片是现有的功能齐全的HTML元素。这个React组件应该用来在这些卡上实现一个新功能:还原更改。

HTML(嗯,它是MVCE版本)

是这样的:

<div id="some-id" class="card float-sm-left menu-visual-card " onclick="(function(event) { console.log('I got clicked, and a modal will spawn' ) })(event)">
    <div class=card-block>
        <h5 class="card-title format-text">Some title</h5>
        <!-- some business elements here -->
    </div>
    <!-- card footer -->
    <div class=customized-indicator-react></div>
</div>

React组件

在tl; dr版本中为:

class CustomizedIndicatorComponent extends React.Component {
    constructor(props) { 
        super(props)

        // business logic
        let active = this.props.active

        this.state = {
            active : active
        }
    }

    toggleActive = () => {
        this.setState({
            ...this.state,
            active : !this.state.active
        })
    }

    // setup
    componentDidMount() { 
        // here's where I tried to add a jQuery onclick listener to stop propagation, only to have the React Component listener get stopped
    }

    // teardown
    componentWillUnmount() { 
        console.log("CustomizedIndicatorComponent destroyed!")
    }

    // the UI logic
    render() {
        if (this.state.active) { 
            return (
                <div>
                    <div 
                        className="badge badge-sm badge-info float-sm-left customized"
                        style={{marginRight:"10px"}}
                    >Customized</div>
                    <div 
                        onClick={(e) => { 
                            e.stopPropagation()
                            this.toggleActive()
                        }}
                        title="Click to undo customizations">
                        <i className="fa fa-undo" aria-hidden="true"></i>
                    </div>
                </div>
            )
        }
        return <div />
    }
}

运行此命令会发生什么?

当我运行它时,它会渲染。但是,当我单击小部件以“停用”该元素时,该容器的事件处理程序仍会触发!

我知道有很多关于此问题或与之相关的问题,但是我找不到的似乎与这个确切的用例有关。

此外,在componentDidMount中添加事件侦听器也无效,因为prevents anything from firing

有什么方法可以使这项工作有效而又不浪费开发人员的工作时间来重构包括父HTMLElements在内的所有内容?

1 个答案:

答案 0 :(得分:0)

您可能会考虑的一种“ hacky”方式是从React组件内部获取父代的ID,并从此处禁用click事件。

如果无法将id作为属性传递给React组件,则可以尝试使用ReactDOM.findDOMNode(this).parentNode.getAttribute("id")来获取它,然后使用以下命令禁用事件:

document.getElementById(id).style.pointerEvents = 'none';