react-native - 在这种情况下如何正确调用 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>
)
}
}
解决方案
使用箭头函数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});
}
});
}
推荐阅读
- symfony - 从工作人员发送电子邮件时,除非引发异常,否则不会发送
- mysql - 从具有不同信息的 3 个表中获取数据
- reactjs - React 功能组件状态变化不会触发子组件重新读取其 props
- php - 根据PHP更改所有页面上的链接
- swift - AppStore 查看崩溃日志
- cassandra - 我可以将计数器类型字段用作 C* 表的主键吗?
- r - 如何解决错误:无法在 RStudio 中分配大小为 70.7 Gb 的向量?
- python-3.x - ITM(爱尔兰横坐标)转换为谷歌地图 Python3 的 GPS
- embedded - 在 Eclipse IDE 上使用带有 MBED 库的矢量偏移表
- gremlin - 如何使用 Gremlin 查询获取特定标签的源顶点和目标顶点之间的所有传入中间顶点的列表?