कैसे प्रतिक्रिया में Esc कुंजी प्रेस का पता लगाने के लिए और इसे कैसे संभालना है


124

मैं अभिकर्मकों पर Esc keypress का पता कैसे लगाऊं? Jquery के समान बात

$(document).keyup(function(e) {
     if (e.keyCode == 27) { // escape key maps to keycode `27`
        // <DO YOUR WORK HERE>
    }
});

एक बार पता लगने के बाद मैं नीचे के घटकों को जानकारी देना चाहता हूं। मेरे पास 3 घटक हैं जिनमें से अंतिम सक्रिय घटक को एस्केप कुंजी प्रेस पर प्रतिक्रिया करने की आवश्यकता है।

जब एक घटक सक्रिय हो जाता है तो मैं एक प्रकार का पंजीकरण करने के बारे में सोच रहा था

class Layout extends React.Component {
  onActive(escFunction){
    this.escFunction = escFunction;
  }
  onEscPress(){
   if(_.isFunction(this.escFunction)){
      this.escFunction()
   }
  }
  render(){
    return (
      <div class="root">
        <ActionPanel onActive={this.onActive.bind(this)}/>
        <DataPanel onActive={this.onActive.bind(this)}/>
        <ResultPanel onActive={this.onActive.bind(this)}/>
      </div>
    )
  }
}

और सभी घटकों पर

class ActionPanel extends React.Component {
  escFunction(){
   //Do whatever when esc is pressed
  }
  onActive(){
    this.props.onActive(this.escFunction.bind(this));
  }
  render(){
    return (   
      <input onKeyDown={this.onActive.bind(this)}/>
    )
  }
}

मेरा मानना ​​है कि यह काम करेगा लेकिन मुझे लगता है कि यह कॉलबैक की तरह होगा। क्या इससे निपटने का कोई बेहतर तरीका है?


क्या आपके पास स्टोर करने के लिए कोई फ्लक्स कार्यान्वयन नहीं है जो इस तरह से करने के बजाय सक्रिय घटक है?
बेन हरे

@ बेनहारे: मैं अभी भी इसके लिए बहुत नया हूं। मैं रिएक्ट में प्रवास की व्यवहार्यता देख रहा हूं। मैंने प्रवाह की कोशिश नहीं की है, इसलिए आप सुझाव दे रहे हैं कि मुझे समाधान के लिए प्रवाह में देखना चाहिए। पुनश्च: ईएससी कुंजी का पता लगाने के बारे में कैसे?
नव

5
बस स्पष्ट करने के लिए, क्या आप पहले स्तर के ब्लॉक की तरह, दस्तावेज़ स्तर पर कीपर डिटेक्शन की तलाश कर रहे हैं? या यह एक इनपुट क्षेत्र के लिए है? आप या तो कर सकते हैं, मुझे यकीन नहीं है कि उत्तर को कैसे फ्रेम किया जाए। यहाँ उदाहरण के लिए एक त्वरित दस्तावेज़-स्तर है: codepen.io/anon/pen/ZOzaPW
ब्रैड कोलथर्स्ट

दस्तावेज़ का स्तर ठीक होगा :)
नव

जवाबों:


228

यदि आप एक दस्तावेज़-स्तरीय कुंजी ईवेंट हैंडलिंग की तलाश कर रहे हैं, तो इसके दौरान बाइंडcomponentDidMount करना सबसे अच्छा तरीका है (जैसा कि ब्रैड कोलथर्स्ट के कोडपेन उदाहरण द्वारा दिखाया गया है ):

class ActionPanel extends React.Component {
  constructor(props){
    super(props);
    this.escFunction = this.escFunction.bind(this);
  }
  escFunction(event){
    if(event.keyCode === 27) {
      //Do whatever when esc is pressed
    }
  }
  componentDidMount(){
    document.addEventListener("keydown", this.escFunction, false);
  }
  componentWillUnmount(){
    document.removeEventListener("keydown", this.escFunction, false);
  }
  render(){
    return (   
      <input/>
    )
  }
}

ध्यान दें कि आपको संभावित त्रुटियों और मेमोरी लीक को रोकने के लिए प्रमुख इवेंट श्रोता को अनमाउंट पर निकालना सुनिश्चित करना चाहिए।

संपादित करें: यदि आप हुक का उपयोग कर रहे हैं, तो आप इस useEffectसंरचना का उपयोग एक समान प्रभाव उत्पन्न करने के लिए कर सकते हैं :

const ActionPanel = (props) => {
  const escFunction = useCallback((event) => {
    if(event.keyCode === 27) {
      //Do whatever when esc is pressed
    }
  }, []);

  useEffect(() => {
    document.addEventListener("keydown", escFunction, false);

    return () => {
      document.removeEventListener("keydown", escFunction, false);
    };
  }, []);

  return (   
    <input />
  )
};

7
में तीसरा तर्क क्या है addEventListenerऔर removeEventListener?
जुआंग

2
@jhuang developer.mozilla.org/en-US/docs/Web/API/EventTarget/… - otions ou useCapture हो सकता है
जूलियो सैटो

2
@ झुआंग यह यूज़ कॉकट्योर तर्क है जो निर्दिष्ट करता है कि क्या उन घटनाओं को कैप्चर किया जाए या नहीं जो आमतौर पर बबल नहीं होती हैंfocus । यह प्रासंगिक नहीं है keydown, लेकिन यह वैकल्पिक नहीं हुआ करता था, इसलिए यह आमतौर पर IE <9 के साथ संगतता के लिए निर्दिष्ट है।
चेस सैंडमैन

मुझे this.escFunctionएक समारोह में शामिल होना function() { this.escFunction(event) }था, अन्यथा यह बिना किसी "कीडाउन" के पेज लोड पर चल रहा था।
M3RS

2
3 तर्क के रूप में 'असत्य' को शामिल करने की आवश्यकता नहीं है। यह डिफ़ॉल्ट रूप से गलत है।
NattyC

25

आप प्रतिक्रियाkeyCode से भागने (27) के लिए सुनना चाहते हैं :SyntheticKeyBoardEvent onKeyDown

const EscapeListen = React.createClass({
  handleKeyDown: function(e) {
    if (e.keyCode === 27) {
      console.log('You pressed the escape key!')
    }
  },

  render: function() {
    return (
      <input type='text'
             onKeyDown={this.handleKeyDown} />
    )
  }
})

ब्रैड कोल्थर्स्ट के कोडपेन को प्रश्न की टिप्पणियों में पोस्ट किया गया है जो अन्य कुंजी के लिए कुंजी कोड खोजने में सहायक है।


15
मुझे लगता है कि यह जोड़ने योग्य है कि रिएक्ट इस घटना को आग नहीं देता है onKeyPressजब कुंजी को दबाया जा रहा है तो ईएससी है और फोकस अंदर है <input type="text" />। उस परिदृश्य में, आप आग का उपयोग कर सकते हैं onKeyDownऔर onKeyUpदोनों सही क्रम में।
टॉम

12

एक कार्यात्मक घटक में इसे पूरा करने का एक और तरीका है , इस तरह का उपयोग करना है useEffectऔर useFunction:

import React, { useEffect } from 'react';

const App = () => {


  useEffect(() => {
    const handleEsc = (event) => {
       if (event.keyCode === 27) {
        console.log('Close')
      }
    };
    window.addEventListener('keydown', handleEsc);

    return () => {
      window.removeEventListener('keydown', handleEsc);
    };
  }, []);

  return(<p>Press ESC to console log "Close"</p>);
}

कंसोल.लॉग के बजाय, आप useStateकुछ ट्रिगर करने के लिए उपयोग कर सकते हैं ।


7

रिएक्ट नेटिव ब्राउज़र ईवेंट को रैप करने के लिए SyntheticKeyboardEvent का उपयोग करता है और यह सिंथेटिक ईवेंट प्रमुख विशेषता प्रदान करता है ,
जिसे आप इसके लिए उपयोग कर सकते हैं:

handleOnKeyDown = (e) => {
  if (['Enter', 'ArrowRight', 'Tab'].includes(e.key)) {
    // select item
    e.preventDefault();
  } else if (e.key === 'ArrowUp') {
    // go to top item
    e.preventDefault();
  } else if (e.key === 'ArrowDown') {
    // go to bottom item
    e.preventDefault();
  } else if (e.key === 'Escape') {
    // escape
    e.preventDefault();
  }
};

3
मजेदार तथ्य यह है कि आप, IE9 और / या फ़ायरफ़ॉक्स 36 या नीचे का समर्थन करने की आवश्यकता है e.keyके लिए Escapeके रूप में वापस आ जाता है Esc#triggered
अगस्त

4

पुन: प्रयोज्य प्रतिक्रिया हुक समाधान के लिए

import React, { useEffect } from 'react';

const useEscape = (onEscape) => {
    useEffect(() => {
        const handleEsc = (event) => {
            if (event.keyCode === 27) 
                onEscape();
        };
        window.addEventListener('keydown', handleEsc);

        return () => {
            window.removeEventListener('keydown', handleEsc);
        };
    }, []);
}

export default useEscape

उपयोग:

const [isOpen, setIsOpen] = useState(false);
useEscape(() => setIsOpen(false))

3
समाधान onEscape फ़ंक्शन को बदलने की अनुमति नहीं देता है। आपको उपयोग करना चाहिए और उपयोग के लिए डिप सरणी के रूप में मी ईसेस्केप को पास करें
नियो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.