首页 > 解决方案 > 在这种情况下如何正确调用 this.setState() ?

问题描述

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

我的忘记密码屏幕中有以下功能

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});    
    }
  });
}

catch 中的 this.setState 返回以下错误:

TypeError:this.setState 不是函数

为了在发生错误时调用 setState() ,我可以做些什么来正确地构造它?

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

好的,我仍然对这个实现有问题,所以我创建了一个带有精简实现的替代类来发布以供审查。当我尝试在提供的代码中使用 this.setState() 时返回的当前错误是:

TypeError: undefined is not an object (评估 this.setState)

在 React 中有多种管理“this”使用场景的方法。根据一些谷歌搜索,看起来 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>
    )
  }
}

标签: react-native

解决方案


使用箭头函数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});    
    }
  });
}

推荐阅读