Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React slow with multiple controlled text inputs

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&hellip;</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&hellip;           </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&hellip;</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>     );   } }); 
like image 848
mrberggg Avatar asked Oct 02 '15 16:10

mrberggg


2 Answers

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. :)

like image 53
Nek Avatar answered Oct 02 '22 13:10

Nek


There are many possible reasons for this to happen. I faced the similar issue and filtered the main cause to:

  • Large State, so it takes up sometime
  • React Dev Tool / Use of non minified react
  • Mutating state data

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} /> 
like image 30
aks Avatar answered Oct 02 '22 13:10

aks