25

I have a React component that is, more or less, a simple textarea where a user can type into. Here is what the code looks like so far:

import React from 'react';
import {connect} from 'react-redux';

function handleChange(event) {
    const {setText} = this.props;

    //is there some way I can detect [ENTER] here and call this.props.add instead?
    setText(event.target.value);
}

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

    render() {
        const {value} = this.props;

        return (
            <div className="list-item">
                <textarea
                    className="form-control"
                    value={value}
                    onChange={handleChange.bind(this)}
                />
            </div>
        );
    }
}

function mapStateToProps(state) {
    return {
        value: state.value
    }
}

function mapDispatchToProps(dispatch) {
    return {
        setText(text) {
            const action = {
                type: 'set-text',
                text: text
            };

            dispatch(action);
        },
        add() {
            const action = {
                type: 'add'
            };

            dispatch(action);
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(TextArea)

This component is connected to a redux store, which is updated every time the user types something into the text area. The redux store sends the new value back to the textarea component, and the textarea component re-renders to display the new value.

While this is working so far, I would like this component to behave differently if the enter key is pressed. Since a change event doesn't expose a keyCode (at least not that I'm aware), I have no idea how to make the handleChange function call the add prop if an enter key is pressed instead of calling the setText prop.

One thing I tried was to attach an onKeyDown handler to the textarea instead, which I could use to detect the enter keyCode (13), but this made me unable to set the text correctly, because if I converted the keyCode attached to the event to a character and appended it to the current value, there would be no way for me to determine whether it should be upper or lower case.

I'm pretty stuck here. I really don't think there's a way for me to detect the enter key on a change event, and a keyDown event doesn't have a way for me to handle all possible inputs. Is there a way I could possibly combine the two?

Thanks in advance!

Michael Parker
  • 12,724
  • 5
  • 37
  • 58
  • Why not to use both of handlers same time? In `onKeyDown` you can check key. If it is ENTER pressed call `event.preventDefault()` to prevent `onChange` call, or if it is not - do nothing – Nick Rassadin Apr 09 '16 at 18:18
  • 1
    Oh, wow, I didn't realize that the change handler would only be called after the keydown handler event bubbled up. I thought they'd both be called at the same time, for some reason. Thanks for the answer! If you post that comment as an answer, I will accept it. – Michael Parker Apr 09 '16 at 19:19
  • Have posted as an answer. Thanks. – Nick Rassadin Apr 09 '16 at 20:33

2 Answers2

43

You can use both of handlers same time.

In onKeyDown you can check key. If it is ENTER pressed call event.preventDefault() to prevent onChange call, or if it is not - do nothing

Javascript event queue doesn't contain change event until default handler for keydown event is called. If you call event.preventDefault() in onKeyDown handler no change event will be fired.

Nick Rassadin
  • 860
  • 7
  • 7
  • "Excluding `event.preventDefault()` in `key[Press|Up|Down]` allows `change` event to be fired." - Key point to note! Thanks! – Deepak Mar 05 '17 at 14:12
0

You may try this.

          onChange={(evt: any) => {               
          }}
          onKeyDown={(evt: any) => {
            const keyCode = evt.keyCode;
            if (keyCode === 8) evt.preventDefault();
          }}
Mujahidul Islam
  • 265
  • 4
  • 8