reactjs - React Native - 未安装的组件
问题描述
我无法理解此错误的来源。控制台说:
无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 LoginScreen 的 componentWillUnmount 方法中取消所有订阅和异步任务。
我用 _isMounted 尝试了这个技巧 - 不起作用。
export default class LoginScreen extends React.Component {
_isMounted = false;
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
errorMessage: null,
logOut: false,
};
this.handleLogin = this.handleLogin.bind(this);
}
componentDidMount() {
this._isMounted = true;
}
componentWillUnmount() {
this._isMounted = false;
}
handleLogin() {
if (this._isMounted) {
const { email, password } = this.state;
firebase.auth().signInWithEmailAndPassword(email, password)
.catch(errorMessage => this.setState({errorMessage}));
this.props.navigation.navigate("Direction", { email, password });
}
};
render() {
return (
<View style={styles.container}>
<Text style={styles.greeting}>
Log in
</Text>
<View style={styles.form}>
<View>
<Text style={styles.inputTitle}>
Email
</Text>
<TextInput style={styles.input}
autoCapitalize="none"
onChangeText={ email => this.setState({email})}
value={this.state.email}>
</TextInput>
</View>
<View>
<Text style={styles.inputTitle}>
Password
</Text>
<TextInput style={styles.input}
secureTextEntry
autoCapitalize="none"
onChangeText={password => this.setState({password})}
value={this.state.password}>
</TextInput>
</View>
<Text style={styles.error}>
{ this.state.errorMessage &&
<Text style={styles.error}>
Incorrect login or password
</Text>
}
</Text>
<TouchableOpacity style={styles.button}
onPress={this.handleLogin}>
<Text style={styles.inputTitle}>
Log in
</Text>
</TouchableOpacity>
<View style={styles.register}>
<Text style={{color: "grey"}}>
Don't have an Account
</Text>
<TouchableOpacity style={styles.secondButton}
onPress={() => { this.props.navigation.navigate("Register")}}>
<Text style={styles.inputTitle}>
Registration
</Text>
</TouchableOpacity>
</View>
</View>
</View>
)
}
}
解决方案
我相信问题出在你的handleLogin
方法上,主要的问题是signInWithEmailAndPassword
返回一个承诺。这意味着流程如下:
- 用户按下登录按钮,并被
handleLogin
执行。 - 此时组件仍处于安装状态,因此流将进入
if (this._isMounted)
。 signInWithEmailAndPassword
返回一个promise,所以如果有错误,catch 块不会立即执行。- 然后,您离开当前组件,导致组件被卸载。
signInWithEmailAndPassword
现在的 catch 块被执行(如果有错误),它尝试更新此时已卸载的组件的状态 -> 繁荣,您看到的控制台警告。
根据您要进行的流程,您可以通过将导航置于then
如下块中来解决此问题,如下signInWithEmailAndPassword
所示:
firebase.auth().signInWithEmailAndPassword(email, password)
.then(() => this.props.navigation.navigate("Direction", { email, password }))
.catch(errorMessage => this.setState({errorMessage}));
但请注意,这意味着您不会在出现错误的情况下离开。
推荐阅读
- docker - 使用 Traefik 仅在内部网络上公开 Docker 数据库服务
- laravel - VueJs 与 Laravel
- python - 如何删除部分数据源?
- php - Laravel 在 null 上调用成员函数 setCookie() - 从中间件返回控制器操作时
- sapui5 - sapui5 路由(无法导航到名称为 xx 的路由,因为该路由不存在)
- java - 使用用户事务在 Tomcat 中的休眠持久性
- android - NativeScript-vue 添加插件失败
- vim - 在 Linux 中使用 vim 替换特定单词
- angular - 使用 QRCodeModule 时未定义 Angular
- dynamics-crm - licensetype 枚举的定义是什么?