gpt4 book ai didi

ReactJS - 向组件添加自定义事件监听器

转载 作者:行者123 更新时间:2023-12-03 12:54:27 24 4
gpt4 key购买 nike

在普通的旧 HTML 中,我有 DIV

<div class="movie" id="my_movie">

以及以下 JavaScript 代码

var myMovie = document.getElementById('my_movie');
myMovie.addEventListener('nv-enter', function (event) {
console.log('change scope');
});

现在我有一个 React 组件,在这个组件内,在 render 方法中,我返回我的 div。如何为我的自定义事件添加事件监听器? (我正在将此库用于电视应用程序 - navigation)

import React, { Component } from 'react';

class MovieItem extends Component {

render() {

if(this.props.index === 0) {
return (
<div aria-nv-el aria-nv-el-current className="menu_item nv-default">
<div className="indicator selected"></div>
<div className="category">
<span className="title">{this.props.movieItem.caption.toUpperCase()}</span>
</div>
</div>
);
}
else {
return (
<div aria-nv-el className="menu_item nv-default">
<div className="indicator selected"></div>
<div className="category">
<span className="title">{this.props.movieItem.caption.toUpperCase()}</span>
</div>
</div>
);
}
}

}

export default MovieItem;

更新#1:

enter image description here

我应用了答案中提供的所有想法。我将导航库设置为 Debug模式,并且我只能根据键盘在菜单项上导航(正如您在屏幕截图中看到的那样,我能够导航到 Movies 4),但是当我将焦点放在菜单中的某个项目或按 Enter 键,我在控制台中看不到任何内容。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class MenuItem extends Component {

constructor(props) {
super(props);
// Pre-bind your event handler, or define it as a fat arrow in ES7/TS
this.handleNVFocus = this.handleNVFocus.bind(this);
this.handleNVEnter = this.handleNVEnter.bind(this);
this.handleNVRight = this.handleNVRight.bind(this);
}

handleNVFocus = event => {
console.log('Focused: ' + this.props.menuItem.caption.toUpperCase());
}

handleNVEnter = event => {
console.log('Enter: ' + this.props.menuItem.caption.toUpperCase());
}

handleNVRight = event => {
console.log('Right: ' + this.props.menuItem.caption.toUpperCase());
}

componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('nv-focus', this.handleNVFocus);
ReactDOM.findDOMNode(this).addEventListener('nv-enter', this.handleNVEnter);
ReactDOM.findDOMNode(this).addEventListener('nv-right', this.handleNVEnter);
//this.refs.nv.addEventListener('nv-focus', this.handleNVFocus);
//this.refs.nv.addEventListener('nv-enter', this.handleNVEnter);
//this.refs.nv.addEventListener('nv-right', this.handleNVEnter);
}

componentWillUnmount() {
ReactDOM.findDOMNode(this).removeEventListener('nv-focus', this.handleNVFocus);
ReactDOM.findDOMNode(this).removeEventListener('nv-enter', this.handleNVEnter);
ReactDOM.findDOMNode(this).removeEventListener('nv-right', this.handleNVRight);
//this.refs.nv.removeEventListener('nv-focus', this.handleNVFocus);
//this.refs.nv.removeEventListener('nv-enter', this.handleNVEnter);
//this.refs.nv.removeEventListener('nv-right', this.handleNVEnter);
}

render() {
var attrs = this.props.index === 0 ? {"aria-nv-el-current": true} : {};
return (
<div ref="nv" aria-nv-el {...attrs} className="menu_item nv-default">
<div className="indicator selected"></div>
<div className="category">
<span className="title">{this.props.menuItem.caption.toUpperCase()}</span>
</div>
</div>
)
}

}

export default MenuItem;

我留下了一些注释行,因为在这两种情况下我都无法记录控制台行。

更新#2:这个导航库不能很好地与带有原始 Html 标签的 React 配合使用,因此我必须设置选项并将标签重命名为使用 aria-*,这样就不会影响 React。

navigation.setOption('prefix','aria-nv-el');
navigation.setOption('attrScope','aria-nv-scope');
navigation.setOption('attrScopeFOV','aria-nv-scope-fov');
navigation.setOption('attrScopeCurrent','aria-nv-scope-current');
navigation.setOption('attrElement','aria-nv-el');
navigation.setOption('attrElementFOV','aria-nv-el-fov');
navigation.setOption('attrElementCurrent','aria-nv-el-current');

最佳答案

如果您需要handle DOM events not already provided by React你必须在组件安装后添加 DOM 监听器:

更新:在 React 13、14 和 15 之间,对影响我的答案的 API 进行了更改。下面是使用 React 15 和 ES7 的最新方法。请参阅answer history对于旧版本。

class MovieItem extends React.Component {

componentDidMount() {
// When the component is mounted, add your DOM listener to the "nv" elem.
// (The "nv" elem is assigned in the render function.)
this.nv.addEventListener("nv-enter", this.handleNvEnter);
}

componentWillUnmount() {
// Make sure to remove the DOM listener when the component is unmounted.
this.nv.removeEventListener("nv-enter", this.handleNvEnter);
}

// Use a class arrow function (ES7) for the handler. In ES6 you could bind()
// a handler in the constructor.
handleNvEnter = (event) => {
console.log("Nv Enter:", event);
}

render() {
// Here we render a single <div> and toggle the "aria-nv-el-current" attribute
// using the attribute spread operator. This way only a single <div>
// is ever mounted and we don't have to worry about adding/removing
// a DOM listener every time the current index changes. The attrs
// are "spread" onto the <div> in the render function: {...attrs}
const attrs = this.props.index === 0 ? {"aria-nv-el-current": true} : {};

// Finally, render the div using a "ref" callback which assigns the mounted
// elem to a class property "nv" used to add the DOM listener to.
return (
<div ref={elem => this.nv = elem} aria-nv-el {...attrs} className="menu_item nv-default">
...
</div>
);
}

}

Example on Codepen.io

关于ReactJS - 向组件添加自定义事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36180414/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com