反应-出现引导程序模态的问题

问题描述 投票:0回答:1

我有一个树状结构。当我在该节点上单击鼠标右键时,将出现contextMenu,在其中可以选择选项-“添加节点”和“编辑节点”。当我单击添加节点时,应该出现引导程序模态,但它不会出现,因为在主体上,我有一个单击事件监听器,负责隐藏上下文菜单。

这是我的点击侦听器方法:

    componentDidMount() {
        document.body.addEventListener('click', this.handleClick.bind(this))
    }
    componentWillUnmount() {
        document.body.removeEventListener('click', this.handleClick.bind(this))
    }

我决定将我的unmount方法传递给ContextMenu组件,并在显示模式之前对其进行调用

<ContextMenu removeEventListener={this.componentWillUnmount.bind(this)} left={this.state.left} top={this.state.top}/>}

ContextMenu:

import React from 'react'
import {MyVerticallyCenteredModal} from './MyVerticallyCenteredModal'

function ContextMenu({removeEventListener, left, top}){

    const [modalShow, setModalShow] = React.useState(false);

    return(
        <React.Fragment>
            <ul className="contextMenu" style={{left: left, top: top}}>
                <li onClick={() => {
                    removeEventListener()
                    setModalShow(true)
                }}>Add Node</li>
                <li>Edit Node</li>
            </ul>

            <MyVerticallyCenteredModal 
                show={modalShow}
                onHide={() => setModalShow(false)}/>
        </React.Fragment>

    )
}

export default ContextMenu

不幸的是,它不起作用:(

更新:

import React, { Component } from 'react'
import {treeActions} from '../_actions'
import { connect } from 'react-redux';
import Node from './Node/Node'
import './style.css'
import ContextMenu from './ContextMenu'

class TreePage extends Component {


    componentDidMount() {
        //this.props.getTree()
        document.body.addEventListener('click', this.handleClick.bind(this))
    }

    state = {activeNode: 0, showContextMenu: false, top:0, left:0}

    setActiveNode(id) {
        this.setState({activeNode: id})
    }
    handleClick() {
        this.setState({showContextMenu: false})
    }
    handleContextMenu(event, id){
        event.preventDefault()

        this.setActiveNode(id)
        this.setState({showContextMenu: true, left: event.clientX, top: event.clientY})

    }

    renderSubNodes(subNodes) {
        const {activeNode} = this.state
        return (
          <ul>
            {subNodes.map((node) => (
                <React.Fragment>
                    <li>
                        <div onContextMenu={(event) => this.handleContextMenu(event, node.id)} className={activeNode===node.id?"bgSelected":""} key={node.id} onClick={() => this.setActiveNode(node.id)}>
                            <Node name={node.name}/>
                        </div>
                        {node.subNodes.length > 0 && this.renderSubNodes(node.subNodes)}
                    </li>

                </React.Fragment>

            ))}
          </ul>
        );
      }

    render() {
        //const {items} = this.props.tree;
        const tree = [
            {
              id: 1,
              name: 'node1',
              subNodes: [
                {
                    id: 4,
                  name: 'node1-1',
                  subNodes: [],
                },
                {
                    id: 5,
                  name: 'node1-2',
                  subNodes: [],
                },
              ],
            },
            {
                id: 2,
              name: 'node2',
              subNodes: [],
            },
            {
                id: 3,
              name: 'node3',
              subNodes: [
                {
                    id: 6,
                  name: 'node3-1',
                  subNodes: [
                    {
                        id: 7,
                      name: 'node3-1-1',
                      subNodes: [],
                    },
                    {
                        id: 8,
                      name: 'node3-1-2',
                      subNodes: [],
                    },
                  ],
                },
                {
                    id: 9,
                  name: 'node3-2',
                  subNodes: [],
                }
              ],
            },
          ];

        return(
            <React.Fragment>
                {this.renderSubNodes(tree)}
                {this.state.showContextMenu? <ContextMenu left={this.state.left} top={this.state.top}/>:''}

            </React.Fragment>
        )
    }
}
function mapState(state){


    return state;
}
const actionCreators = {
    getTree: treeActions.getTree
}

const connectedApp = connect(mapState, actionCreators)(TreePage)
export {connectedApp as TreePage}

ContextMenu:

import React from 'react'
import {MyVerticallyCenteredModal} from './MyVerticallyCenteredModal'

function ContextMenu({left, top}){

    const [modalShow, setModalShow] = React.useState(false);

    return(
        <React.Fragment>
            <ul className="contextMenu" style={{left: left, top: top}}>
                <li onClick={(event) => {
                    event.stopPropagation()
                    setModalShow(true)
                }}>Add Node</li>
                <li>Edit Node</li>
            </ul>

            <MyVerticallyCenteredModal 
                show={modalShow}
                onHide={() => setModalShow(false)}/>
        </React.Fragment>

    )
}

export default ContextMenu
reactjs
1个回答
0
投票

HTML DOM API具有称为“事件冒泡”的概念。简单来说,就是单击节点时。该事件一直沿父树向上冒泡。这导致触发您身上的onClick。

使用event.stopPropagation()可以停止此行为。这将阻止事件冒泡。

您的示例将onClick函数更改为:

(event) => {
    event.stopPropagation()
    setModalShow(true)
}

这样,您就不必在主体节点上卸载事件处理程序。

© www.soinside.com 2019 - 2024. All rights reserved.