Reputation: 1458
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
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
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