简体   繁体   English

如何确保始终在ReactJS子组件内部调用事件侦听器?

[英]How to ensure an event listener is always called inside a ReactJS child component?

I have a ReactJS component below. 我在下面有一个ReactJS组件。 I want to listen for a key down even if my component is not in focus. 我想听一个按键,即使我的组件不在焦点上。 It will always be rendered but it is not the only component on the web page. 它将始终呈现,但它不是网页上的唯一组件。 The event listener will call a function when I push the SHIFT key down. 当我按下SHIFT键时,事件侦听器将调用一个函数。 The component is not the topmost component on my web page; 该组件不是我网页上最重要的组件; it has a parent. 它有一个父母。

Component extends React.Component {

    componentWillMount(): void {
        document.addListener('keyDown', this._handleKeyDown);
    }

    componentWillUnmount(): void {
        document.removeListender('keyDown', this._handleKeyDown);
    }

}

Sometimes it will behave properly when I push a button but sometimes I actually have to click on this component again to get it to acknowledge the key press. 有时候,当我按下一个按钮时,它会正常工作,但有时,我实际上不得不再次单击该组件,以使其能够确认按键。

How can I ensure it always listens for the key press? 我如何确保它总是监听按键? Is it advisable to add an event listener to document in a lower level component? 是否建议将事件侦听器添加到较低级别组件中的文档?

pen here -> http://codepen.io/dagman/pen/mAOrVP 笔在这里-> http://codepen.io/dagman/pen/mAOrVP

const App = ({ 
    handleOnKeyDown,
    keyCode
}) => (
    <div>
        <input 
            style={styles.input}
            onKeyDown={handleOnKeyDown} 
            placeholder="Press any key to see it's code on right" 
        />
        <span style={styles.span}>{keyCode}</span>
    </div>
);

class AppContainer extends React.Component {
    constructor(props) {
        super();
        this.state = {
            keyCode: null
        };
    }
    handleOnKeyDown(e) {
        this.setState({
            keyCode: e.keyCode
        });
    }
    render() {
        return(
            <App 
                handleOnKeyDown={this.handleOnKeyDown.bind(this)}
                keyCode={this.state.keyCode}
            />
        );
    }
}

const mountNode = document.getElementById('app');
const styles = {
    input: {
        width: 300,
        height: 50
    },
    span: {
        color: 'white',
        marginLeft: 5
    }
};

ReactDOM.render(
    <AppContainer />,
    mountNode
);

Is it what you were asking about? 这是您要问的吗?

It wasn't working because I had a very large invisible div in front of my clickable element. 这没有用,因为在我的clickable元素前面有一个非常大的不可见div。 I made the div have no pointer events and then I was able to get my keyDown function consistently working. 我使div没有指针事件,然后能够使我的keyDown函数始终运行。

The technique above will work. 上面的技术将起作用。 You can put document.addEventListener inside a child React component. 您可以将document.addEventListener放在子React组件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM