ReactJS-컴포넌트에 커스텀 이벤트 리스너 추가
평범한 오래된 자바 스크립트에서는 DIV가 있습니다.
<div class="movie" id="my_movie">
및 다음 자바 스크립트 코드
var myMovie = document.getElementById('my_movie');
myMovie.addEventListener('nv-enter', function (event) {
console.log('change scope');
});
이제이 구성 요소 내부의 render 메서드에 React 구성 요소가 있으며 내 div를 반환합니다. 내 사용자 지정 이벤트에 대한 이벤트 리스너를 추가하려면 어떻게해야합니까? (이 라이브러리를 TV 앱용으로 사용하고 있습니다- 탐색 )
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 :
나는 답변에 제공된 모든 아이디어를 적용했습니다. 탐색 라이브러리를 디버그 모드로 설정하고 키보드를 기준으로 만 메뉴 항목을 탐색 할 수 있습니다 (스크린 샷에서 볼 수 있듯이 영화 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;
두 경우 모두 콘솔 행을 기록 할 수 없기 때문에 일부 행에 주석을 달았습니다.
Update #2: This navigation library does not work well with React with its original Html Tags, so I had to set the options and rename the tags to use aria-* so it would not impact 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');
If you need to handle DOM events not already provided by React you have to add DOM listeners after the component is mounted:
Update: Between React 13, 14, and 15 changes were made to the API that effect my answer. Below is the latest way using React 15 and ES7. See answer history for older versions.
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>
);
}
}
You could use componentDidMount and componentWillUnmount methods:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class MovieItem extends Component
{
_handleNVEvent = event => {
...
};
componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('nv-event', this._handleNVEvent);
}
componentWillUnmount() {
ReactDOM.findDOMNode(this).removeEventListener('nv-event', this._handleNVEvent);
}
[...]
}
export default MovieItem;
우선, 커스텀 이벤트는 기본적으로 React 컴포넌트와 잘 작동하지 않습니다. 따라서 <div onMyCustomEvent={something}>
렌더링 기능에서 말할 수 없으며 문제에 대해 생각해야합니다.
둘째, 사용중인 라이브러리에 대한 설명서를 살펴본 후 이벤트가 실제로 발생 document.body
하므로 작동하더라도 이벤트 처리기가 트리거되지 않습니다.
대신 componentDidMount
애플리케이션의 어딘가에서 다음을 추가하여 nv-enter를들을 수 있습니다.
document.body.addEventListener('nv-enter', function (event) {
// logic
});
그런 다음 콜백 함수 내에서 구성 요소의 상태를 변경하는 함수를 누르거나 원하는 작업을 수행합니다.
참고 URL : https://stackoverflow.com/questions/36180414/reactjs-add-custom-event-listener-to-component
'Program Tip' 카테고리의 다른 글
자식 뷰 컨트롤러의 topLayoutGuide (0) | 2020.11.05 |
---|---|
Websocket 전송 안정성 (재 연결 중 Socket.io 데이터 손실) (0) | 2020.11.05 |
여러 데이터베이스 엔진에서 사용할 수있는 공통 형식의 데이터가있는 샘플 데이터베이스는 어디에서 찾을 수 있습니까? (0) | 2020.11.05 |
WPF에서 인쇄 /보고하는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.05 |
Collections.max () 서명에서 T가 Object에 묶여있는 이유는 무엇입니까? (0) | 2020.11.05 |