2015-08-27 12 views
10

Próbuję zaimplementować bardzo podstawowe wykrywanie naciśnięć klawiszy i nie mogę w ogóle uruchomić tego działania. Mam gołą składnik, który powinien być podniesienie na razie onKeyDown ale nic nie zostanie wylogowany w konsoli:Nie reaguje na zdarzenie z kluczem w dół

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    } 

    handleKeyDown(event) { 
    console.log('handling a key press'); 
    } 

    render() { 
    return (
     <ChildComponent onKeyDown={this.handleKeyDown} /> 
    ); 
    } 
} 

React.render(<App />, document.getElementById('app')); 

Odpowiedz

4

Problem polega na tym, że ChildComponent nie jest składnikiem, ale fabryką komponentów. Zostanie on zastąpiony wynikiem renderowania elementu utworzonego w tej fabryce.

Włóż ChildComponent do elementu div i dołącz dowolny detektor zdarzeń do elementu div, a nie ChildComponent. Wymień <div> z <span>, jeśli potrzebujesz wbudowanego wyświetlacza.

let {Component} = React; 

class ChildComponent extends Component { 
    render() { 
    return (<child-component>click me</child-component>); 
    } 
} 

class App extends Component { 
    handleClick(event) { 
    console.log('handling a key press'); 
    } 

    render() { 
    return (<div onClick={this.handleClick}><ChildComponent /></div>); 
    } 
} 

React.render(<App />, document.getElementById('app')); 

Zobacz go w akcji na codepen

+0

Zauważyłem, że próbuję zastosować style. Zamiast stosować do elementu DOM najwyższego poziomu wewnątrz komponentu, style są po prostu upuszczane na podłogę. –

28

trzeba przypisać tabIndex -attribute za element (element owijania na przykład) aby otrzymywać impulsy. Następnie przechodzą procedurę obsługi keyDown do niej z rekwizytami:

import React from 'react'; 
import { render } from 'react-dom'; 

class ChildComponent extends React.Component { 
    constructor(props) { 
    super(props); 
    } 
    render() { 
    return (
     <div tabIndex="0" onKeyDown={this.props.handleKeyDown}>Fooo</div> 
    ); 
    } 
} 

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    } 

    handleKeyDown(event) { 
    console.log('handling a key press'); 
    } 

    render() { 
    return (
     <ChildComponent handleKeyDown={() => this.handleKeyDown()} /> 
    ); 
    } 
} 

render(<App />, document.getElementById('app')); 
+0

Jakiś powód, dla którego potrzebuje indeksu tabulatora? – user1095118

+1

@ user1095118 Jest to jedyny sposób, w jaki elementy obok łączy i elementów formularza mogą otrzymywać fokus na klawiaturze, a tym samym naciśnięcia klawiszy. Jest ustawiony na zero, aby nie zastąpić rodzimej kolejności tabulatorów. Więcej informacji można znaleźć na stronie http://webaim.org/techniques/keyboard/tabindex. –

0

w aplikacji mój zespół pracuje nad używamy react-hotkey. Niestety, React nie obsługuje miksów ze składnią ES6, ale jeśli jesteś fajny z jakimś babelem, możesz spróbować.

let App = React.createClass({ 
    mixins: [hotkey.Mixin('handleKeyDown')], 

    componentDidMount() { 
    hotkey.activate(); 
    }, 

    componentWillUnmount() { 
    hotkey.disable(); 
    }, 

    handleKeyDown(event) { 
    console.log('handling a key press'); 
    }, 

    render() { 
    return (
     <ChildComponent /> 
    ); 
    } 
}); 

React.render(<App />, document.getElementById('app')); 
6

DOM element chce się koncentrować w celu odebrania zdarzenia klawiatury. Jeśli nie chcesz zhakować elementu za pomocą tabIndex lub contentEditable, aby go ustawić, możesz użyć natywnych detektorów zdarzeń DOM na window i zdefiniować inną procedurę obsługi w każdym komponencie obsługującym zdarzenia klawiatury.

Tylko pamiętaj, aby usunąć detektor zdarzeń kiedy że odmontowuje składowe więc wszystkie elementy nie są obsługi przez cały czas:

componentWillMount: function() { 
    window.addEventListener('keydown', this.handleKeyDown); 
    }, 

    componentWillUnmount: function() { 
    window.removeEventListener('keydown', this.handleKeyDown); 
    }, 

Ponadto, nie wydaje się być npm, który zapewnia podobną funkcjonalność jeśli to łatwiejsze: https://www.npmjs.com/package/react-keydown

+0

Pamiętaj, aby powiązać obsługę zdarzeń w konstruktorze, jeśli chcesz, aby 'ten' był składnikiem: ' this.handleKeyDown = this.handleKeyDown.bind (this) ' – boxtrain

+0

nie zawsze jednak. powiąż go tylko ze sobą, jeśli ten składnik powinien również obsługiwać te zdarzenia. w przypadku złożonego interfejsu użytkownika (takich jak aplikacje internetowe) używam klas 'InputHandler', które obsługują i kierują WSZYSTKIE zdarzenia użytkowników do wszystkich komponentów. jest ładniejsze, niż gdyby każdy/wszystkie komponenty posiadały swoje własne funkcje obsługi, ponieważ jeśli w oknie pojawi się wiele detektorów keydown, wszystkie te komponenty 'handleKeydowns' będą próbowały obsłużyć zdarzenie w porównaniu z 1' InputHandler' obsługując wszystkie zdarzenia. również, jest przypadek, w którym nic nie jest zrobione z 'tym' w funkcji obsługi - w takim przypadku nie musisz również wiązać. – Benny

Powiązane problemy