How to prevent react component click event bubble to document?

可紊 提交于 2020-01-14 04:42:05

问题


How to prevent react component click event from bubble up to document ?

I can sure that there must be something was wrong with it!

So, may be I should help myself fix it!

I just have a box component which has a click event listener, and there are some link components in that box which are effected by a document click event. How can I remove this document click event?

Can someone do me a favor?

More details info can be found in following links!

Here is the code link : https://github.com/ant-design/ant-design/issues/6576

  1. Click has no effect, it should link to item3!

  1. Remove document's click event

  1. After that, it works!

What's wrong with this?

import React, { Component } from 'react';
import PropTypes from 'prop-types';

import logo from './logo.svg';
import './App.css';

// import SideBox from './SideBox.js';

// import ContentBox from './ContentBox.js';

/*import SidebarExample from './test.js';*/

// import ReactDOMServer from 'react-dom/server';

import {
    BrowserRouter as Router,
    Route,
    Link
} from 'react-router-dom';

import Item1 from './components/Item1.js';
import Item2 from './components/Item2.js';
import Item3 from './components/Item3.js';


import {Menu, Icon} from 'antd';

import 'antd/dist/antd.css';

const SubMenu = Menu.SubMenu;


const element = <h1>Hello, world</h1>;


const elements = () => {
    return(
        <h1>Hello, world</h1>
    );
};

const routes = [
    {
        path: '/',
        exact: true,
        sidebar: () => <div>item1</div>,
        main: () => <div><Item1 /></div>
    },
    {
        path: '/item2',
        sidebar: () => <div>item2</div>,
        main: () => <div><Item2 /></div>
    },
    {
        path: '/item3',
        sidebar: () => <div>item3</div>,
        main: () => <div><Item3 /></div>
    }
]

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            message: props.message,
            styles: props.styles,
            Any: props.any,
            width: props.width,
            theme: 'dark',
            current: '1'
        };
        this.handleMenuClick = this.handleMenuClick.bind(this);
        this.handleClick = this.handleClick.bind(this);
    };
    handleClick(e) {
        console.log('click ', e);
        this.setState({
            current: e.key,
        });
    };
    // ES7 property initializer syntax
    handleMenuClick = (e) => {
        e.preventDefault();
        // e.stopPropagation();
        // e.nativeEvent.stopImmediatePropagation();
        console.log('this is:', this);
        console.log("clicked === \n", e);
        if(this.state.styles === "App-SideBox-init"){
            this.setState({
                message: "e.key",
                styles: "App-SideBox-New",
                width: "width: 40px;"
            });
        }
        if(this.state.styles === "App-SideBox-New"){
            this.setState({
                message: "Hello!",
                styles: "App-SideBox-init",
                width: "width: 300px;"
            });
        }
        console.log("this.state.message === ", this.state.message);
        console.log("this.state.styles === ", this.state.styles);
    };
    componentDidMount() {
        /*window.addEventListener('scroll', this.onScroll.bind(this), false);*/
        // window.removeEventListener('click', this.handleMenuClick.bind(this), false);
        // window.removeEventListener('click', this.handleClick.bind(this), false);
    };
    render() {
        return (
            <div className="App">
                <div className="App-header">
                    <img id="img" src={logo} className="App-logo" alt="logo" style={this.props.width}/>
                    <h2>Welcome to React</h2>
                </div>
                <div className="App-SideBox">
                    <div className={this.state.styles}>
                        <Router>
                                <div>
                                    <div style={{ display: 'flex' }}>
                                        <div style={{
                                                padding: '10px',
                                                width: '30%',
                                                background: '#f0f0f0'
                                            }}>
                                            <div className="SideBox-body" style={{ display: 'flex' }}>
                                                <Menu
                                                        theme={this.state.theme}
                                                        onClick={this.handleClick}
                                                        style={{ width: 240 }}
                                                        defaultOpenKeys={['sub1']}
                                                        selectedKeys={[this.state.current]}
                                                        mode="inline"
                                                    >
                                                    <SubMenu
                                                            key="sub1"
                                                            title={
                                                                <span>
                                                                    <Icon type="mail" />
                                                                    <span>Navigation One</span>
                                                                </span>
                                                            }
                                                        >
                                                        <Menu.Item key="1">
                                                            <Link to="/"> item1</Link>
                                                        </Menu.Item>
                                                        <Menu.Item key="2">
                                                            <Link to="/item2">item2</Link>
                                                        </Menu.Item>
                                                        <Menu.Item key="3">
                                                            <Link to="/item3">item3</Link>
                                                        </Menu.Item>
                                                    </SubMenu>
                                                </Menu>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </Router>
                    </div>
                    {/*onClick={this.handleMenuClick}*/}
                    <div onClick={this.handleMenuClick} className="App-SideBox-btn">
                        <span>icon</span>
                    </div>
                </div>
                <div className="App-body">
                    <Router>
                        <div>
                            <div>
                                <div style={{ flex: 1, padding: '10px' }}>
                                    {
                                        routes.map((route, index) => (
                                            <Route
                                                key={index}
                                                path={route.path}
                                                exact={route.exact}
                                                component={route.main}
                                            />
                                        ))
                                    }
                                </div>
                            </div>
                        </div>
                    </Router>
                </div>
            </div>
        );
    }
};

App.defaultProps = {
    message: 'Hello!',
    styles: 'App-SideBox-init'
};

App.propTypes = {
    message: PropTypes.string.isRequired,
    styles: PropTypes.string.isRequired,
    width: PropTypes.string
};

export default App;

回答1:


Just make all event handlers on the parent component, and then pass them to children by using props!



来源:https://stackoverflow.com/questions/44711549/how-to-prevent-react-component-click-event-bubble-to-document

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!