如何在这种情况下正确调用this.setState()?

时间:2019-11-16 22:55:37

标签: react-native

在这种情况下如何正确调用this.setState()?

我的ForgotPassword屏幕具有以下功能

handleForgotPassword(){

  if(!this.validateInputs()) return;

  const {email} = this.state;
  const auth = firebase.auth();
  //const setState = this.setState;

  auth.sendPasswordResetEmail(email).then(function() {
    this.setState({passwordEmailSent:true});
  }).catch(function(error) {
    //alert(error.message);
    let errorMessage;
    if(error.message.includes('There is no user')){
      errorMessage = 'No users match the provided email address';
      this.setState({errorMessage});    
    }
  });
}
捕获中的

this.setState返回以下错误:

TypeError:this.setState不是函数

发生错误时,我该怎么做才能正确构造结构以便调用setState()?

=====更新=====

好的,我仍然对该实现有疑问,因此我创建了一个替代类,其中包含一个简化的实现,以供发布。当我尝试在提供的代码中使用this.setState()时返回的当前错误是:

TypeError:未定义不是对象(正在评估this.setState)

在React中有多种方法来管理“此”使用场景。基于一些谷歌搜索,React团队建议在构造函数中将功能绑定到“ this”。我也喜欢这种方法,因为它提供了清晰而一致的方法。那么,您能否澄清一下为什么这段代码当前将this.setState()视为未定义,以及我可以对代码进行哪些修改以解决此问题?

以下代码:

import React from 'react';
import { Text, TextInput, View, Button } from 'react-native';
import firebase from 'react-native-firebase';

export default class ForgotPassword2 extends React.Component {
  state = { email: '', errorMessage: null, passwordEmailSent:false }

  constructor(props){
    super(props);
    this.validateInputs = this.validateInputs.bind(this);
    this.handleForgotPassword = this.handleForgotPassword.bind(this);
  }

  validateInputs(){
    const {email} = this.state;

    if(email.length === 0){
      this.setState({errorMessage:'Email is required'});
      return false;
    }

    return true;
  }

handleForgotPassword(){

  alert('function called');
  if(!this.validateInputs()) return;

  const {email} = this.state;
  const auth = firebase.auth();

  auth.sendPasswordResetEmail(email).then(function() {
    //this.setState({passwordEmailSent:true});
    alert('pwd reset email sent');
  }).catch(function(error) {
      alert(error.message);
    let errorMessage;
    if(error.message.includes('There is no user')){
      alert('no matching user');
      errorMessage = 'No users match the provided email address';
      this.setState({errorMessage});
    }
  });
}

render() {
    return(
      <View>
          {this.state.errorMessage &&
            <Text style={{ color: 'red' }}>
              {this.state.errorMessage}
            </Text>}

          <TextInput
            onChangeText={email => this.setState({ email })}
            value={this.state.email}
          />
          <Button onPress={this.handleForgotPassword} title="Send Email 2"></Button>
        </View>
    )
  }
}

1 个答案:

答案 0 :(得分:0)

使用箭头函数,this将是组件类的上下文:

handleForgotPassword = () => {

  if(!this.validateInputs()) return;

  const {email} = this.state;
  const auth = firebase.auth();
  //const setState = this.setState;

  auth.sendPasswordResetEmail(email).then(() => {
    this.setState({passwordEmailSent:true});
  }).catch((error) => {
    //alert(error.message);
    let errorMessage;
    if(error.message.includes('There is no user')){
      errorMessage = 'No users match the provided email address';
      this.setState({errorMessage});    
    }
  });
}

不使用箭头功能的示例:

constructor(props) {
  super(props);
  this.handleForgotPassword = this.handleForgotPassword.bind(this);
}

handleForgotPassword(){
  const context = this;
  if(!context.validateInputs()) return;

  const {email} = context.state;
  const auth = firebase.auth();
  //const setState = context.setState;

  auth.sendPasswordResetEmail(email).then(function() {
    context.setState({passwordEmailSent:true});
  }).catch(function(error) {
    //alert(error.message);
    let errorMessage;
    if(error.message.includes('There is no user')){
      errorMessage = 'No users match the provided email address';
      context.setState({errorMessage});    
    }
  });
}