I have a form with multiple text inputs. I have them all set up as controlled inputs. When typing, there is a lag of up to several seconds for the new text to display in the field. Here is an example field:
<label>Event Name</label> <input type="text" placeholder="Title" className="form-control" name="title" value={this.state.event.title} onChange={this.handleChange} />
I can't figure out what's causing it to be so slow or what to do to fix it.
UPDATED: Here's the component, should be enough to show what's going on.
let CreateEventForm = React.createClass({ submit: function () {}, handleChange: function(e){ let value = e.target.value; let name = e.target.name; if(value === 'true'){ value = true; } if(value === 'false'){ value = false; } // If true/false toggle old let oldState = this.state.event[name]; if(typeof oldState === 'boolean'){ value = !oldState; } // If is array if(name.indexOf('[]') > -1){ name = name.replace('[]', ''); oldState = this.state.event[name]; var pos = oldState.indexOf(value); if(pos > -1){ oldState.splice(pos, 1); } else { oldState.push(value); } value = oldState; } let event = this.state.event; event[name] = value; this.setState({event: event}); console.log(this.state.event); }, getClasses(field, additionalClasses = []) { // If a string is passed for additional class, make array if(!Array.isArray(additionalClasses)){ additionalClasses = [additionalClasses]; } let useDefaultColumns = additionalClasses.filter(function(className){ return className.indexOf('col-') > -1; }).length === 0; let hasError = function(){ let fields = Array.isArray(field) ? field : [field]; return fields.filter(function(field){ return !this.props.isValid(field); }.bind(this)).length > 0; }.bind(this)(); return classnames({ 'col-sm-4': useDefaultColumns, 'form-group': true, 'has-error': hasError }, additionalClasses); }, render: function () { return ( <form ref="eventForm" onSubmit={this.submit}> <SavedModal isOpen={this.state.saved} reset={this.resetForm} style={this.state.modals.styles} /> <h3>Info</h3> <div className="row"> <div className={this.getClasses('title')}> <label>Event Name</label> <input type="text" placeholder="Title" className="form-control" name="title" value={this.state.event.title} onChange={this.handleChange} /> {this.renderHelpText(this.props.getValidationMessages('title'))} </div> </div> <div className="row"> <div className={this.getClasses('type')}> <label>Event Type</label> <select name="type" className="form-control" value={this.state.event.type} onChange={this.handleChange} onBlur={this.props.handleValidation('type')}> <option value="">Select Event Type…</option> {this.state.calendarTypes.map(function (type, key) { return <option value={type.name} key={key}>{type.name}</option> })} </select> {this.renderHelpText(this.props.getValidationMessages('type'))} </div> </div> <h3>Duration</h3> <div className="row"> <div className="form-group col-sm-2"> <input type="checkbox" name="allDay" checked={this.state.event.allDay} onChange={this.handleChange}/> All Day </div> </div> <div className="row"> <div className="form-group col-sm-2"> <input type="checkbox" name="repeats" checked={this.state.event.repeats} onChange={this.handleChange}/> Repeats… </div> <br/><br/> </div> <h3>Location</h3> <div className="row"> <div className={this.getClasses('location')}> <select name="location" className="form-control" value={this.state.event.location} onBlur={this.props.handleValidation('location')} onChange={this.handleChange}> <option value="">Select a Location…</option> {this.state.locations.map(function (location, key) { return ( <option value={location.name} key={key}>{location.name}</option> ); })} </select> {this.renderHelpText(this.props.getValidationMessages('location'))} </div> </div> <h3>Description</h3> <div className="row"> <div className={this.getClasses('description')}> <label>Write a description:</label> <textarea className="form-control" name="description" value={this.state.event.description} onChange={this.handleChange} onBlur={this.props.handleValidation('description')} rows="10"></textarea> {this.renderHelpText(this.props.getValidationMessages('description'))} </div> </div> <h3>Event Details</h3> <div className="row"> <div className={this.getClasses('fee')}> <label>Fee:</label> <input type="text" className="form-control" name="fee" value={this.state.event.fee} onChange={this.handleChange} onBlur={this.props.handleValidation('fee')}/> {this.renderHelpText(this.props.getValidationMessages('fee'))} </div> </div> <div className="row"> <div className="col-sm-12"> <button className="btn btn-primary" type="submit"> Create Event </button> </div> </div> </form> ); } });
I had a similar situation and my solution was to disable React Dev Tools. They were affecting input fields somehow. The problem is it's not enough to refresh a page if you have clicked React Dev Tools tab. They are still affecting your inputs. You have to open new page to stop them. You can also remove them from Chrome completely but I don't recommend doing this 'cause they are useful. :)
There are many possible reasons for this to happen. I faced the similar issue and filtered the main cause to:
Whatever may be the reason, I found a quick fix for this. If you just want to store it to the state but not using it for live rendering. Then you can safely replace the 'onChange' to 'onBlur'. This has no dealay and lag. If you know any other case where this will not work, do let me know!
Change the code as follow:
<label>Event Name</label> <input type="text" placeholder="Title" className="form-control" name="title" value={this.state.event.title} onBlur={this.handleChange} />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With