我无法理解此错误的来源。 控制台说:
无法对未挂载的组件执行 React 状态更新。这是无操作,但它表示应用程序中存在内存泄漏。若要修复,请取消 LoginScreen 中的组件 WillUnmount 方法中的所有订阅和异步任务。
我用_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
返回一个承诺,因此如果出现错误,catch 块不会立即执行。- 然后,您离开当前组件,导致组件被卸载。
- 现在执行
signInWithEmailAndPassword
的 catch 块(如果出现错误(,它尝试更新此时卸载的组件的状态 -> 繁荣,您看到的控制台警告。
根据您要要使用的流,您可以通过让导航位于then
块中来解决此问题,如下所示signInWithEmailAndPassword
:
firebase.auth().signInWithEmailAndPassword(email, password)
.then(() => this.props.navigation.navigate("Direction", { email, password }))
.catch(errorMessage => this.setState({errorMessage}));
但请注意,这意味着如果发生错误,您将不会离开。