У меня есть регистры и я отправляю данные в функцию Firebase. У меня проблема в том, что когда две функции вложены, они регистрируются и хранятся в Firebase, но есть предупреждения (ниже). Но когда я удаляю функцию push-данных, предупреждения нет. Я хочу иметь возможность зарегистрироваться и иметь возможность сохранять данные. Или я могу написать две отдельные функции, и когда onPress может вызывать две функции одновременно?
Это мой код:
handleSignUp = () => {
const { username, email, passwordOne } = this.state;
const { history } = this.props;
auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
// Create a user in your own accessible Firebase Database too
db.doCreateUser(authUser.user.uid, username, email)
.then(() => {
this.setState({ ...INITIAL_STATE }, () => {
history.navigation.navigate("MainScreenNavigator");
});
})
.catch(error => this.setState({ errorMessage: error.message }));
})
.catch(error => this.setState({ errorMessage: error.message }));
};
И предупреждение:
Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
функция doCreactUser
export const doCreateUser = (id, username, email) =>
db.ref(`users/${id}`).set({
username,
email,
});
Полный код:
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
StatusBar,
TextInput,
TouchableOpacity,
KeyboardAvoidingView
} from "react-native";
import Logo from "../components/Logo";
import { Actions } from "react-native-router-flux";
import { auth, db, firebase } from "../firebase/";
const INITIAL_STATE = {
username: "",
email: "",
passwordOne: "",
passwordTwo: "",
errorMessage: null
};
export default class Signup extends Component<{}> {
constructor(props) {
super(props);
this.state = { INITIAL_STATE };
}
handleSignUp = () => {
const { username, email, passwordOne } = this.state;
const { history } = this.props;
auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
// Create a user in your own accessible Firebase Database too
db.doCreateUser(authUser.user.uid, username, email)
.then(() => {
this.setState({ ...INITIAL_STATE }, () => {
history.navigation.navigate("MainScreenNavigator");
});
})
.catch(error => this.setState({ errorMessage: error.message }));
})
.catch(error => this.setState({ errorMessage: error.message }));
};
goBack() {
Actions.pop();
}
render() {
const {
username,
email,
passwordOne,
passwordTwo,
} = this.state;
const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === "" ||
email === "" ||
username === "";
const display = isInvalid ? "none" : "flex";
return (
<View style = {styles.container}>
<StatusBar backgroundColor = "#99d066" barStyle = "light-content" />
<Logo />
<KeyboardAvoidingView>
<TextInput
style = {styles.inputBox}
underlineColorAndroid = "rgba(0,0,0,0)"
placeholder = "Full Name"
placeholderTextColor = "#000"
autoCapitalize = "none"
selectionColor = "#fff"
keyboardType = "default"
onSubmitEditing = {() => this.passwordOne.focus()}
onChangeText = {username => this.setState({ username })}
value = {this.state.username}
/>
<TextInput
style = {styles.inputBox}
underlineColorAndroid = "rgba(0,0,0,0)"
placeholder = "Email"
placeholderTextColor = "#000"
autoCapitalize = "none"
selectionColor = "#fff"
keyboardType = "email-address"
onSubmitEditing = {() => this.passwordOne.focus()}
onChangeText = {email => this.setState({ email })}
value = {this.state.email}
/>
<TextInput
style = {styles.inputBox}
underlineColorAndroid = "rgba(0,0,0,0)"
placeholder = "Password"
secureTextEntry = {true}
placeholderTextColor = "#000"
autoCapitalize = "none"
ref = {input => (this.passwordOne = input)}
onChangeText = {passwordOne => this.setState({ passwordOne })}
value = {this.state.passwordOne}
/>
<TextInput
style = {styles.inputBox}
underlineColorAndroid = "rgba(0,0,0,0)"
placeholder = "Confirm Password"
secureTextEntry = {true}
placeholderTextColor = "#000"
autoCapitalize = "none"
ref = {input => (this.passwordTwo = input)}
onChangeText = {passwordTwo => this.setState({ passwordTwo })}
value = {this.state.passwordTwo}
/>
</KeyboardAvoidingView>
<TouchableOpacity style = {[styles.button, { display }]}>
<Text style = {styles.buttonText} onPress = {this.handleSignUp}>
Sign up
</Text>
</TouchableOpacity>
{this.state.errorMessage && (
<Text style = {{ color: "#b71c1c", textAlign: "center" }}>
{this.state.errorMessage}
</Text>
)}
<View style = {styles.signupTextCont}>
<Text style = {styles.signupText}>Already have an account?</Text>
<TouchableOpacity onPress = {this.goBack}>
<Text
style = {styles.signupButton}
onPress = {() => this.props.navigation.navigate("Login")}
>
{" "}
Sign in
</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({...});
Извините, я обновил полный код
Здесь this.state = { INITIAL_STATE };
это вызовет у вас проблему, потому что это сделает ключ INITIAL_STATE внутри вашего состояния. Вы должны выкладывать или делать this.state = INITIAL_STATE
@TieuDuongTu, ммм, вы можете захотеть реорганизовать это, вы хотите обработать случай регистрации пользователя, но как насчет входа в систему уже зарегистрированного пользователя? Так что вместо auth.doCreateUserWithEmailAndPassword(email, passwordOne)
, что-то вроде firebase .auth() .signInWithEmailAndPassword(email, password)
. Я мог бы направить вас больше, но очистите эти файлы выше, отметив, что есть в вашей организации redux, это немного сбивает с толку.
Похоже, вы вызываете
handleSignUp
, когда компонент еще не смонтирован (или больше не смонтирован) в пользовательском интерфейсе, а это означает, что вызовsetState
игнорируется. Итак, вызовdb.doCreateUser
завершается без проблем, он просто не может установить состояние вашего компонента в реакции и, следовательно, не может обновить пользовательский интерфейс (потому что компонент не отображается / больше не отображается в пользовательском интерфейсе. С кодом, который вы предоставили , больше сложно сказать.