简体   繁体   中英

key binding in react.js

was trying to implement key binding in react.js. did some research, but still wondering what's the cleanest way to do it. For example,

if (event.keyCode == 13 /*enter*/) {
  function()
}
if (event.keyCode == 27 /*esc*/) {
  anotherfunction()
}

I ended up binding the keydown event when the component mounted and unmounted:

...

componentDidMount: function() {
  $(document.body).on('keydown', this.handleKeyDown);
},

componentWillUnMount: function() {
  $(document.body).off('keydown', this.handleKeyDown);
},

handleKeyDown: function(event) {
  if (event.keyCode == 13 /*enter*/) {
    this.okAction();
  }
  if (event.keyCode == 27 /*esc*/) {
    this.cancelAction();
  }
},

render: function() {
  return this.state.showDialog ? (
    <div className="dialog" onKeyDown={this.handleKeyDown}>

...

There's probably a better way to do this. The function is used as a part of a dialog component: https://github.com/changey/react-dialog

step 1 : Define it in constructor

  constructor(props) {
    super(props);

    this.state = {        
    }
    this.handleEnterKeyPress = this.handleEnterKeyPress.bind(this)
  }

step 2 : Write it in render method

 render() {   
            return (             
                   <input className ="pageText" type="text" value= "value" onKeyPress = {this.handleEnterKeyPress} />                       
            )
          }

step 3 : write the respective function in the class

handleEnterKeyPress(e) {
    if (e.charCode == 13) {
      // your code
    }
  }

Here is my search component, please take a look at the onSearch function. I'm using no keyboard binding to accomplish the escape key clearing input and defocusing.

import React from "react"
import _debounce from "lodash.debounce"
import "./stylesheets/search"

export default class Search extends React.Component {

  displayName = "Search"

  static propTypes = {
    bucketName: React.PropTypes.string,
    placeholder: React.PropTypes.string,
    onSearchUpdated: React.PropTypes.func,
  }

  state = {
    search: "",
    placeholder: "Search",
    bucketName: "",
  }

  componentWillMount() {
    this.delayedCallback = _debounce((event) => {
      let search = event.target.value
      this.setState({
        search,
      })
      this.props.onSearchUpdated(search, this.props.bucketName)
    })
  }

  onSearch = (event) => {

    if (event.keyCode === 27) {
      event.target.value = ''
      this.refs.input.blur()
    } else {
      this.refs.input.focus()
    }

    event.persist()
    this.delayedCallback(event)
  }

  render() {
    return (
      <div className="search">
        <div className="row">
          <div className="col-xs-12 search__container form-group">
            <input
              ref="input"
              className="form-control search__field"
              placeholder={this.props.placeholder}
              name="search__field"
              id="search__field"
              type="text"
              onKeyDown={this.onSearch}
            />
          </div>
        </div>
      </div>
    )
  }
}

Don't yet have enough rep to comment on your answer yet, but I would like to suggest an improvement.

Try using event namespacing when you bind/unbind these. This is especially important when binding events to the body, as it allows you to unbind without disrupting any other bindings of the same type:

See:
https://css-tricks.com/namespaced-events-jquery/

componentDidMount: function() {
  $(document.body).on('keydown.awesomeNamespaceName', this.handleKeyDown);
},

componentWillUnMount: function() {
  $(document.body).off('keydown.awesomeNamespaceName', this.handleKeyDown);
},

handleKeyDown: function(event) {
  if (event.keyCode == 13 /*enter*/) {
    this.okAction();
  }
  if (event.keyCode == 27 /*esc*/) {
    this.cancelAction();
  }
},

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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