我正在使用React-Native,并试图创建一个登录/注册表单。注册表单主要在工作,但是,当我专注于InputText时,闪烁的选择器/光标会向右对齐半秒钟,然后变为居中(文本处于并且应居中)。不知道是什么原因造成的。我认为这可能与我不知道的一些React-Native属性有关。
当InputText聚焦时,我也删除了占位符文本,但是,如果我在没有输入任何其他内容的情况下聚焦其他东西(密码和确认密码),则在我的4个InputText上占位符将永远不会返回。电子邮件和用户名可以正常工作。我认为这可能与我的特定代码有关,因为2可以正常工作-但我无法发现错误。
感谢所有帮助。我已经创建了自定义组件,它们包含InputText。这是我的外部组件,而字段组件可以在下面找到:
import React, { Component } from 'react';
import { ScrollView, StyleSheet, TextInput, Text, View, Image, Button, ImageBackground, TouchableHighlight, TouchableOpacity } from 'react-native';
import firebase from '../firebase.js';
import Field from './Fields/Field.js';
class Auth extends Component {
state = {
username: "",
email: "",
password: "",
confirmPassword: "",
error: {
username: "",
email: "",
password: "",
confirmPassword: ""
},
focus: {
username: false,
email: false,
password: false,
confirmPassword: false
},
placeholder: {
username: "Choose Username",
email: "Enter Email",
password: "Choose Password",
confirmPassword: "Confirm Password"
},
validation: {
username: {
min: 7,
max: 15,
},
password: {
min: 7,
max: 15
}
},
form: "Sign In"
}
onChangeUsername = async (event, validate) => {
//the cursor jumps sometimes.
var curEvent={...event};
var oldError = { ...this.state.error };
if (validate === true)
{
var letterNumber = /^[0-9a-zA-Z]+$/;
console.log(curEvent.nativeEvent.text+ "Hello")
if (curEvent.nativeEvent.text===""){oldError.username=""; this.setState({ username: curEvent.nativeEvent.text, error: oldError })}
else if ((curEvent.nativeEvent.text.length < this.state.validation.username.min) || (curEvent.nativeEvent.text.length > this.state.validation.username.max)) { oldError.username = "Username should be between " + this.state.validation.username.min + " and " + this.state.validation.username.max + " characters";console.log(curEvent.nativeEvent.text+ "Hello"); this.setState({ username: curEvent.nativeEvent.text, error: oldError })}
else if (curEvent.nativeEvent.text.match(letterNumber)===null)
{oldError.username="Usernames can only contain alphanumeric characters"; this.setState({ username: curEvent.nativeEvent.text, error: oldError })}
else {
oldError.username="";
this.setState({ username: curEvent.nativeEvent.text, error: oldError });
let lowerCaseUsername = curEvent.nativeEvent.text.toLowerCase();
await firebase.database().ref().child("Usernames").orderByKey().equalTo(lowerCaseUsername).once('value', (snapshot) => {
var exists = (snapshot.val() !== null);
if(exists === true)
{
oldError.username="Username already in use";}
else {oldError.username=""}
this.setState({error: oldError })
}).catch(error=>{oldError.username=error.message; this.setState({ username: curEvent.nativeEvent.text, error: oldError })});
}
}
else oldError.username = "";
}
onChangeEmail = (event) => {
//cursor moves to loight if you lcick it. wtf. // placeholders never return for password and confirmpassword/
var oldError = { ...this.state.error };
if(event.nativeEvent.text === "")
oldError.email = "";
else if(event.nativeEvent.text.indexOf('@') < 1 || event.nativeEvent.text.indexOf('.') === -1)
oldError.email="Invalid email format";
else if (event.nativeEvent.text.indexOf('@') > 0 ){
if (event.nativeEvent.text.lastIndexOf(".") - event.nativeEvent.text.indexOf('@') < 2)
oldError.email="Invalid email format";
else if(event.nativeEvent.text.charAt(event.nativeEvent.text.length - 1) === ".")
oldError.email="Invalid email format";
//any other non alpha numeric characters //non alphanumeric characters either side of the @ and .
else
oldError.email = "";}
this.setState({ email: event.nativeEvent.text, error: oldError });
}
switchForm = () => {
if (this.state.form === "Sign In")
this.setState({form:"Sign Up",username:"",password:"",email:"",confirmPassword:"",error:{email:"",username:"",password:"",confirmPassword:""},focus:{email:false,username:false,password:false,confirmPassword:false}})
if (this.state.form === "Sign Up")
this.setState({form:"Sign In",username:"",password:"",email:"",confirmPassword:"",error:{email:"",username:"",password:"",confirmPassword:""},focus:{email:false,username:false,password:false,confirmPassword:false}})
}
onChangePassword = (event, validate) => {
var oldError = { ...this.state.error };
if (validate === true){
if ((event.nativeEvent.text.length < this.state.validation.password.min) || (event.nativeEvent.text.length > this.state.validation.password.max)) { oldError.password = "Password should be between " + this.state.validation.password.min + " and " + this.state.validation.password.max + " characters"; }
else { oldError.password = "" };
}
else { oldError.password = "" };
this.setState({ password: event.nativeEvent.text, error: oldError })
}
onChangeConfirmPassword = (event) => {
var oldError = { ...this.state.error };
if (this.state.password !== event.nativeEvent.text) {
oldError.confirmPassword = "Passwords do not match";
}
else { oldError.confirmPassword = "" };
this.setState({ confirmPassword: event.nativeEvent.text, error: oldError })
}
createUser = () => {
if ((this.state.error.username === "" || this.state.error.email === "" || this.state.error.password === "" || this.state.error.password === "") && (this.state.username !== "" || this.state.email !== "" || this.state.password !== "" || this.state.password !== ""))
{
firebase.auth().createUserWithEmailAndPassword(this.state.username, this.state.password).catch(error => {
var errorCode = error.code;
var oldError = { ...this.state.error };
if (errorCode === "auth/invalid-email") { oldError.email = "Invalid email address" }
else if (errorCode === "auth/weak-password") { oldError.password = "Password should be between " + this.state.validation.password.min + " and " + this.state.validation.password.max + " characters" }
else if (errorCode === "auth/email-already-in-use") { oldError.email = "This email is already registered" }
});
}
}
userLogIn = () => {
firebase.auth().signInWithEmailAndPassword(this.state.username, this.state.password).catch(error => {
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode === "auth/invalid-email") { this.setState({ error: "Invalid email or password." }) }
else if (errorCode === "auth/wrong-password") { this.setState({ error: "Invalid email or password." }) }
else if (errorCode === "auth/user-not-found") { this.setState({ error: "Invalid email or password." }) }
console.log(error.code);
console.log(error.message);
})
}
render() {
let formSwitch;
let fields;
if(this.state.form==="Sign Up"){
formSwitch = (<React.Fragment>
<View style={{ width: "100%", height: "2%" }}></View>
<TouchableHighlight title="Sign Up" style={{ backgroundColor: "dodgerblue", width: "60%", height: "8%", borderRadius: 5, flexDirection: "row", justifyContent: "center", alignItems: "center" }} onPress={this.createUser}><Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }} >SIGN UP</Text></TouchableHighlight>
<View style={{ width: "100%", height: "2%" }}></View>
<TouchableHighlight title="Sign Up" style={{ backgroundColor: "dodgerblue", width: "20%", height: "5%", borderRadius: 5, flexDirection: "row", justifyContent: "center", alignItems: "center" }} onPress={this.switchForm}><Text style={{ fontSize: 15, fontWeight: "bold", color: "white" }} >SIGN IN</Text></TouchableHighlight>
<View style={{ width: "100%", height: "20%" }}></View>
</React.Fragment>)
fields=(<React.Fragment>
<Field secure = {false} value={this.state.email} error={this.state.error.email} focus={this.state.focus.email} placeholder={this.state.placeholder.email} focusFunction={() => { this.setState({ focus: { username: false, email: true, password: false, confirmPassword: false }, email: "" }) }} changeFunction={this.onChangeEmail}></Field>
<Text style={{ color: "white" }}>{this.state.error.email}</Text>
<Field secure = {false} value={this.state.username} error={this.state.error.username} focus={this.state.focus.username} placeholder={this.state.placeholder.username} focusFunction={() => { this.setState({ focus: { username: true, email: false, password: false, confirmPassword: false }, username: "" }) }} changeFunction={(event)=>{this.onChangeUsername(event,true)}}></Field>
<Text style={{ color: "white" }}>{this.state.error.username}</Text>
<Field secure = {true} value={this.state.password} error={this.state.error.password} focus={this.state.focus.password} placeholder={this.state.placeholder.password} focusFunction={() => { this.setState({ focus: { username: false, email: false, password: true, confirmPassword: false }, password: "" }) }} changeFunction={(event)=>{this.onChangePassword(event,true)}}></Field>
<Text style={{ color: "white" }}>{this.state.error.password}</Text>
<Field secure = {true} value={this.state.confirmPassword} error={this.state.error.confirmPassword} focus={this.state.focus.confirmPassword} placeholder={this.state.placeholder.confirmPassword} focusFunction={() => { this.setState({ focus: { username: false, email: false, password: false, confirmPassword: true }, confirmPassword: "" }); console.log(this.state.placeholder.confirmPassword) }} changeFunction={this.onChangeConfirmPassword}></Field>
<Text style={{ color: "white" }}>{this.state.error.confirmPassword}</Text>
</React.Fragment>)}
else if (this.state.form === "Sign In"){
formSwitch = (<React.Fragment>
<View style={{ width: "100%", height: "2%" }}></View>
<TouchableHighlight title="Sign Up" style={{ backgroundColor: "dodgerblue", width: "60%", height: "8%", borderRadius: 5, flexDirection: "row", justifyContent: "center", alignItems: "center" }} onPress={this.createUser}><Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }} >SIGN IN</Text></TouchableHighlight>
<View style={{ width: "100%", height: "2%" }}></View>
<TouchableHighlight title="Sign Up" style={{ backgroundColor: "dodgerblue", width: "20%", height: "5%", borderRadius: 5, flexDirection: "row", justifyContent: "center", alignItems: "center" }} onPress={this.switchForm}><Text style={{ fontSize: 15, fontWeight: "bold", color: "white" }} >SIGN UP</Text></TouchableHighlight>
<View style={{ width: "100%", height: "20%" }}></View>
</React.Fragment>)
fields = (<React.Fragment>
<Field value={this.state.username} error={this.state.error.username} focus={this.state.focus.username} placeholder={"Username"} focusFunction={() => { this.setState({ focus: { username: true, email: false, password: false, confirmPassword: false }, username: "" }) }} changeFunction={(event)=>{this.onChangeUsername(event,false)}}></Field>
<Field secure = {true} value={this.state.password} error={this.state.error.password} focus={this.state.focus.password} placeholder={"Password"} focusFunction={() => { this.setState({ focus: { username: false, email: false, password: true, confirmPassword: false }, password: "" }) }} changeFunction={(event)=>{this.onChangePassword(event,false)}}></Field>
</React.Fragment>)}
return (
<ImageBackground source={require('../../Images/back8.gif')} resizeMode="cover" style={{ width: "100%", height: "100%", backgroundColor: "#eeeeee", flexDirection: "column", alignItems: "center", justifyContent: "flex-start" }}>
<View style={{ width: "100%", height: "30%", margin: -20, marginBottom: -35, flexDirection: "row", alignItems: "center", justifyContent: "space-around" }}>
<Image source={require('../../Images/Logo.png')} style={{ width: "60%", height: "100%" }} resizeMode="contain" ></Image>
</View>
{fields}
{formSwitch}
</ImageBackground>
);
}
}
export default Auth;
这是字段组件:
import React, {Component} from 'react';
import {View, TextInput} from 'react-native';
const Field = (props) =>{
let colourIndicator;
if (props.value!=="")
{colourIndicator=<View style={{backgroundColor:props.error === ""?"#00ff7f":"#ffa500", margin: 0, height:15, width: 15, borderRadius:50}}></View>}
return(
<View style={{ width: "100%", height: "10%", margin: "2%", backgroundColor:"transparent",flexDirection:"row", justifyContent:"center", alignContent:"center"}}>
<View style={{backgroundColor:"transparent", height:"100%", marginTop: "2%", marginRight: "-10%", width: 20, flexDirection: "column",justifyContent:"space-around", alignItems:"center"}}>
<View style={{backgroundColor:"transparent", margin: 0, height:15, width: 15, borderRadius:50}}></View>
</View>
<TextInput
value={props.value}
autoCorrect={false}
spellCheck={false}
onChange={props.changeFunction}
style={{ width: "80%", height: "100%", color:"white", padding: "5%", margin: "2%", paddingLeft:"10%", paddingRight:"10%", letterSpacing:2, borderRadius: 5, backgroundColor: props.focus?"black":"rgba(0,0,0,0.5)" }}
placeholder={props.focus===true?"":props.placeholder}
selectionColor= "white"
underlineColorAndroid= 'transparent'
placeholderTextColor="rgba(255,255,255,0.5)"
autoComplete={"off"}
autoCapitalize={"none"}
textAlign={'center'}
secureTextEntry={props.secure}
onFocus={props.focusFunction}
/>
<View style={{backgroundColor:"transparent", height:"100%", marginTop: "2%", marginLeft: "-10%", width: 20, flexDirection: "column",justifyContent:"space-around", alignItems:"center"}}>
{colourIndicator}
</View>
</View>
);
}
export default Field;