Lazhar
Lazhar

Reputation: 1458

KeyPress to detect 'Enter' blocks any data entry on an Input text field

Beginner with React and I am bumping into an issue. I have a profile page where the user can change each field (First name, Email, etc.) and once 'Enter' is pressed, it saves that particular field (redux/axios/promise).

The problem I have is that when I use onKeyPress/Down/Up as event trigger, it blocks any data entry. Meaning, i cannot type anything in the field, as if it was read-only or blocked. If I use onChange, it works.

class Account extends Component {

    constructor( props ) {
        super(props);

        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(e) {

        if( e.key == 'Enter' ) { // this is detected (i console.logged it)

            e.preventDefault(); // also tried without these
            e.stopPropagation(); // also tried without these

            // this is triggered but the text field doesn't change so it updates nothing
            this.props.setUserKvPair( e.target.name, e.target.value );
        }
    }

    render() {

        return (
            <div className="app-account row">

                <div className="component-container col-12">
                    <div className="inner">

                        <p className="form-group">
                            <label className="form-text text-muted">Email Address</label>
                            <input 
                                type="text" 
                                name="email"
                                className="form-control" 
                                value={this.props.user.email} 
                                onKeyDown={this.handleChange} />
                        </p>
                        <p className="form-group">
                            <label className="form-text text-muted">First Name</label>
                            <input 
                                type="text" 
                                name="first_name"
                                className="form-control" 
                                value={this.props.user.first_name} 
                                onKeyPress={this.handleChange} />
                        </p>
                    </div>
                </div>

            </div>
        );
    }

}

const mapStateToProps = ( state ) => {
    return {
        user: state.user.data,
        properties: state.properties.data,
    }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(userActions, dispatch);
}


export default connect( mapStateToProps, mapDispatchToProps )(Account);

Basically, everything works but it's just that the value of the text input doesn't change unless I use onChange.

How can I remove that blockage/readonly on the field?

Upvotes: 2

Views: 482

Answers (2)

Andrii Starusiev
Andrii Starusiev

Reputation: 7774

How can you write something in the input with a value and without onChange?

value={this.props.user.email} without onChange this mean your input is read only

https://jsfiddle.net/69z2wepo/84207/

Upvotes: 1

canaan seaton
canaan seaton

Reputation: 6868

I recommend using a form for this as it grants free onEnter functionality without having to wire up a bunch of different event handlers. Also, I suggest using Controlled Components which does make use of the onChange handler but caches all input values in the component state. This makes using the data extremely easy.

See below code for an example

import React, { Component } from "react";

class SomeComponent extends Component {
    constructor() {
        super();

        this.state = {
            text_1: "",
            text_2: ""
        };

        this.submitHandler = this.submitHandler.bind(this);
    }

    submitHandler(e) {
        e.preventDefault();

        const { text_1, text_2 } = this.state;

        console.log(text_1, text_2);
    }

    render() {
        return (
            // Using a form gives free on 'Enter' functionality
            <form onSubmit={this.submitHandler}>
                {/* Controlled Component 1 */}
                <input
                    type="text"
                    value={this.state.text_1}
                    onChange={e => this.setState({ text_1: e.target.value })}
                />

                {/* Controlled Component 2 */}
                <input
                    type="text"
                    value={this.state.text_2}
                    onChange={e => this.setState({ text_2: e.target.value })}
                />
            </form>
        );
    }
}

Upvotes: 1

Related Questions