SetState导致react.js中的应用程序崩溃

时间:2017-06-27 10:13:50

标签: javascript reactjs

我最近开始处理 react.js ,在创建登录页面时,我使用setstate方法将userEmail的值设置为文本框。

我创建了一种检查电子邮件地址有效性的方法,每次用户输入新信时我都会调用它。

handleChangeInEmail(event) {
    var value = event.target.value;
    console.log("change in email value" + value);
    if(validateEmailAddress(value) == true) {
      this.setState(function() {
        return {
              showInvalidEmailError : false,
              userEmailForLogin: value,
           }
     });
   } else {
     this.setState(function() {
       return {
              showInvalidEmailError : true,
              userEmailForLogin: value

      }
  });
}

此方法和userEmailForLogin staterender方法中传递为

<EmailLoginPage  
   userEmailForLogin = {this.state.userEmailForLogin}
   onHandleChangeInEmail= {this.handleChangeInEmail}
/>

我正在使用该方法验证电子邮件地址,方法是

validateEmailAddress : function(emailForLogin) {
        if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(emailForLogin))  {  
            return true; 
        }  
        return false;  
    },

我正在使用此方法并将 EmailLoginPage 呈现为<input type="text" name="" placeholder="Enter Email" className="email-input-txt" onChange={props.onHandleChangeInEmail} value = {props.userEmailForLogin}/>

这在正常情况下运行正常,但是当我尝试输入一个大型电子邮件地址yjgykgkykhhkuhkjhgkghjkhgkjhghjkghjghghkghbghbg@gmail.com时,它会崩溃

IMO状态的频繁变化导致了这种情况,但我无法理解应该做些什么来摆脱这种情况。

3 个答案:

答案 0 :(得分:0)

使用去抖动的解决方案。这样可以减少多个setState。

DEMO:https://jsfiddle.net/vedp/kp04015o/6/

class Email extends React.Component {
    constructor (props) {
        super(props)
        this.state = { email: "" }
    }

    handleChange = debounce((e) => {
        this.setState({ email: e.target.value })
    }, 1000)

    render() {
        return (
            <div className="widget">
                <p>{this.state.email}</p>
                <input onChange={this.handleChange} />
            </div>
        )
    }
}

React.render(<Email/>, document.getElementById('container'));


function debounce(callback, wait, context = this) {
  let timeout = null 
  let callbackArgs = null

  const later = () => callback.apply(context, callbackArgs)

  return function() {
    callbackArgs = arguments
    clearTimeout(timeout)
    timeout = setTimeout(later, wait)
  }
}

答案 1 :(得分:0)

我认为问题仅在于regex,我尝试与其他人一起工作。

而不是在if/else函数内写change,而只是写这样:

change(event) {
    var value = event.target.value;
    this.setState({
       showInvalidEmailError : this.validateEmailAddress(value),
       value: value,
    });
}

从此回答中复制regexHow to validate email address in JavaScript?

检查工作解决方案:

&#13;
&#13;
class App extends React.Component {
    
    constructor(){
        super();
        this.state = {
            value: '',
            showInvalidEmailError: false
        }
        this.change = this.change.bind(this);
    }

    change(event) {
        var value = event.target.value;
        this.setState(function() {
            return {
                showInvalidEmailError : this.validateEmailAddress(value),
                value: value,
            }
        });
    }
    
    validateEmailAddress(emailForLogin) {
        var regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        if(regex.test(emailForLogin)){
          return true;
      }
        return false;
    }

    render() {
        return(
            <div>
                <input value={this.state.value} onChange={this.change}/>
                <br/>
                valid email: {this.state.showInvalidEmailError + ''}
            </div>
        );
    }
}

ReactDOM.render(
    <App/>, 
    document.getElementById("app")
);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以使用Lodash的去抖功能,这样就不会调用检查功能,除非用户在x时间内停止输入(在我的场景下300ms)。

_this.debounceCheck = debounce((value) => {
  if(validateEmailAddress(value)) {
    this.setState(function() {
      return {
        showInvalidEmailError : false,
        userEmailForLogin: value,
      }
    });
  } else {
    this.setState(function() {
      return {
        showInvalidEmailError : true,
        userEmailForLogin: value
      }
    });
  }
}, 300)

handleChangeInEmail(event) {
  _this.debounce(event.target.value)
}