Javascript 使用多个受控文本输入时反应缓慢

Javascript 使用多个受控文本输入时反应缓慢,javascript,reactjs,Javascript,Reactjs,我有一个具有多个文本输入的表单。我把它们都设置为受控输入。键入时,新文本在字段中显示的滞后时间长达几秒钟。以下是一个示例字段: <label>Event Name</label> <input type="text" placeholder="Title" className="form-control" name="title" value={this.state.event.title} o

我有一个具有多个文本输入的表单。我把它们都设置为受控输入。键入时,新文本在字段中显示的滞后时间长达几秒钟。以下是一个示例字段:

<label>Event Name</label>
<input type="text" 
       placeholder="Title"
       className="form-control"
       name="title"
       value={this.state.event.title}
       onChange={this.handleChange} />
事件名称
我不知道是什么原因导致它这么慢,或者该怎么做来修复它

更新:这是组件,应该足以显示发生了什么

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>
    );
  }
});
让CreateEventForm=React.createClass({
提交:函数(){},
handleChange:函数(e){
设值=e.target.value;
让name=e.target.name;
如果(值=='true'){
值=真;
}
如果(值=='false'){
值=假;
}
//如果为真/假,则切换为旧
让oldState=this.state.event[name];
if(typeof oldState=='boolean'){
值=!oldState;
}
//If-is数组
if(name.indexOf('[]')>-1){
name=name.replace(“[]”,“”);
oldState=this.state.event[name];
var pos=旧状态indexOf(值);
如果(位置>-1){
旧状态拼接(位置1);
}否则{
oldState.push(值);
}
值=旧状态;
}
让event=this.state.event;
事件[名称]=值;
this.setState({event:event});
console.log(this.state.event);
},
getClasses(字段,additionalClasses=[]){
//如果为其他类传递了字符串,则生成数组
if(!Array.isArray(附加类)){
additionalClasses=[additionalClasses];
}
让useDefaultColumns=additionalClasses.filter(函数(类名){
返回className.indexOf('col-')>-1;
}).长度===0;
设hasError=function(){
让fields=Array.isArray(field)?field:[field];
返回字段。过滤器(函数(字段){
return!this.props.isValid(字段);
}.bind(this)).length>0;
}.绑定(这个)();
返回类名({
“col-sm-4”:使用默认列,
“表单组”:true,
“has error”:hasError
},额外类别);
},
渲染:函数(){
返回(
信息
事件名称
{this.renderHelpText(this.props.getValidationMessages('title'))}
事件类型
选择事件类型&hellip;
{this.state.calendarTypes.map(函数(类型,键){
返回{type.name}
})}
{this.renderHelpText(this.props.getValidationMessages('type'))}
期间
整天
重复&hellip;


位置 选择一个位置&hellip; {this.state.locations.map(函数(位置,键){ 返回( {location.name} ); })} {this.renderHelpText(this.props.getValidationMessages('location'))} 描述 写一个描述: {this.renderHelpText(this.props.getValidationMessages('description'))} 活动详情 费用: {this.renderHelpText(this.props.getValidationMessages('fee'))} 创建事件 ); } });
下面是一个输入模式的示例。最主要的是将您的输入作为一个组件,将更改传递给父级,但如果它们相同,则不会从道具更新

我也遇到过类似的情况,我的解决方案是禁用React-Dev工具。它们以某种方式影响了输入字段。问题是,如果单击了React Dev Tools选项卡,则刷新页面是不够的。它们仍在影响您的输入。你必须打开新页面才能阻止它们。您也可以完全从Chrome中删除它们,但我不建议这样做,因为它们很有用。:)

发生这种情况的原因有很多。我面临类似的问题,并筛选出主要原因:

  • 大州,所以需要一段时间
  • React开发工具/使用非小型React
  • 变异状态数据
不管是什么原因,我找到了一个快速解决办法。如果只想将其存储到状态,而不想将其用于实时渲染。然后您可以安全地将“onChange”替换为“onBlur”。这没有延迟和延迟。如果你知道任何其他情况下,这将不起作用,一定要让我知道

更改代码如下:

<label>Event Name</label>
<input 
   type="text" 
   placeholder="Title"
   className="form-control"
   name="title"
   value={this.state.event.title}
   onBlur={this.handleChange} />
事件名称

我已经让redux记录器中间件花了足够的时间来创建这个输入延迟。所以,试着禁用它

我的问题是我的状态对象很复杂,因此导致了渲染问题。我的解决方案是管理组件中注释的状态,然后更新容器状态

const { data, onEdit } = props;
const { containerNotes } = data;

const [notes, setNotes] = useState('');

useEffect(
  () => {
    setNotes(containerNotes);
  },
  [containerNotes],
);

const onChangeNotes = () => ({ target: { value } }) => {
  setNotes(value);
};

const onBlurNotes = (prop) => ({ target: { value } }) => {
  const newData = update(data, {
    [prop]: { $set:  value },
  });
  onEdit(newData);
};

return (
  <input 
     type="text" 
     placeholder="Title"
     name="title"
     value={notes}
     onChange={onChangeNotes()}
     onBlur={onBlurNotes('containerNotes')}
 />
)
const{data,onEdit}=props;
const{containerNotes}=数据;
const[notes,setNotes]=useState(“”);
使用效果(
() => {
setNotes(containerNotes);
},
[containerNotes],
);
const onChangeNotes=()=>({target:{value}})=>{
设置注释(值);
};
const onBlurNotes=(prop)=>({target:{value}}})=>{
const newData=更新(数据{
[prop]:{$set:value},
});
onEdit(新数据);
};
返回(
)

这是我找到的一个修复程序。它在onBlur中设置父状态。请检查一下这个

import React, { useState } from 'react';
import MUIField from '@material-ui/core/TextField';
import _ from 'lodash';

export default (props) => {
  const [value, setValue] = useState(props.defaultValue);
  const prop = _.omit(props, ['onChange', 'value', 'defaultValue']);

  return (
      <MUIField {...prop} value={value}
                onChange={e => { setValue(e.target.value); }}
                onBlur={() => {
                  props.onChange({ target:{ value }});
              }}/>);
};

import React,{useState}来自“React”;
从“@material ui/core/TextField”导入MUIField;
从“lodash”进口;
导出默认值(道具)=>{
const[value,setValue]=使用状态(props.defaultValue);
const prop=uz.omit(props,['onChange','value','defaultValue']);
返回(
{setValue(e.target.value);}
onBlur={()=>{