构建自定义输入组件

时间:2020-07-12 05:10:01

标签: react-native

我已经建立了一个注册页面,这是它的代码:

import React, { Component } from "react";
import firebase from "../util/firebase";
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  TextInput,
  ActivityIndicator,
  Alert,
} from "react-native";
import {
  widthPercentageToDP as wp,
  heightPercentageToDP as hp,
} from "react-native-responsive-screen";
import { MaterialCommunityIcons } from "@expo/vector-icons";

export default class Register extends React.Component {
  //State Constructor
  constructor() {
    super();
    this.state = {
      confirmPassword: "",
      email: "",
      password: "",
      isLoading: false,
      buttonColor: "#8b898a",
      inputColor: "grey",
    };
  }
  //Change Button Color if Input Fieldes Are filled
  changeColorIfFilled() {
    let currentColor = this.state.buttonColor;
    if (
      this.state.email != "" &&
      this.state.password != "" &&
      this.state.confirmPassword != ""
    ) {
      currentColor = "#7356bf";
    } else currentColor = "#8b898a";
    this.setState({ buttonColor: currentColor });
  }
  //Update Input State to Current Input Value
  updateInputVal = (val, prop) => {
    const state = this.state;
    state[prop] = val;
    this.changeColorIfFilled();
  };
  //Register Function
  registerUser = () => {
    //If Input Blank Return Alert
    if (this.state.email === "" && this.state.password === "") {
      Alert.alert("Enter details to signup!");
    }
    //If Passwords Dont Match Return Alert
    else if (this.state.password !== this.state.confirmPassword) {
      Alert.alert("Passwords Don't Match");
    }
    //If Everything OK Register User
    else {
      this.setState({
        isLoading: true,
      });
      firebase
        //Activate Auth
        .auth()
        //New Function
        //Create New User
        .createUserWithEmailAndPassword(
          this.state.email,
          this.state.password
          // this.state.confirmPassword
        )
        //After Creating User
        .then(() => {
          console.log("User registered successfully!");
          this.setState({
            isLoading: false,
            email: "",
            password: "",
            // confirmPassword: "",
          });
          this.props.navigation.navigate("Next Screen");
        })
        .catch(function (error) {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          if (errorCode == "auth/weak-password") {
            alert("The password is too weak.");
          } else if (errorCode == "auth/invalid-email") {
            alert("Email is Invalid");
          } else if (errorCode == "auth/email-already-in-use") {
            alert("Email is Already in use!");
          } else {
            alert(errorMessage);
          }
          console.log(error);
        });
    }
  };

  render() {
    if (this.state.isLoading) {
      return (
        <View style={styles.preloader}>
          <ActivityIndicator size="large" color="#9E9E9E" />
        </View>
      );
    }
    return (
      <View style={styles.container}>
        <View style={styles.titleContainer}>
          <Text style={styles.title}>
            Create an account and join our studio
          </Text>
        </View>
        <View style={styles.inputsContainer}>
          <View style={styles.emailInputsContainer}>
            <TextInput
              style={styles.emailInput}
              placeholder="Email"
              value={this.state.email}
              onChangeText={(val) => this.updateInputVal(val, "email")}
            />
          </View>
          <View style={styles.passInputsContainer}>
            <MaterialCommunityIcons
              name="eye-off"
              size={24}
              color="black"
              style={styles.eyeIcon}
            />
            <TextInput
              style={styles.passwordInput}
              placeholder="Password"
              value={this.state.password}
              onChangeText={(val) => this.updateInputVal(val, "password")}
              maxLength={15}
              secureTextEntry={true}
            />
          </View>
          <View style={styles.cPassInputsContainer}>
            <TextInput
              style={styles.confirmPasswordInput}
              placeholder="ConfirmPassword"
              value={this.state.confirmPassword}
              onChangeText={(val) =>
                this.updateInputVal(val, "confirmPassword")
              }
              maxLength={15}
              secureTextEntry={true}
            />
          </View>
        </View>
        <View style={styles.buttonContainer}>
          <TouchableOpacity
            style={[
              styles.loginButton,
              { backgroundColor: this.state.buttonColor },
            ]}
            title="Continue"
            onPress={() => this.registerUser()}
          >
            <Text style={styles.loginText}>Continue</Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  //Views
  container: {
    flex: 1,
    backgroundColor: "#ffffff",
  },
  titleContainer: {
    height: hp(10),
    width: wp(65.2),
    alignItems: "center",
    marginLeft: wp(17.4),
    marginRight: wp(17.4),
    marginTop: hp(17.1),
  },
  inputsContainer: {
    marginTop: hp(7.9),
    alignItems: "center",
  },
  emailInputsContainer: {
    flexDirection: "row-reverse",
  },
  passInputsContainer: {
    flexDirection: "row-reverse",
  },
  cPassInputsContainer: {
    flexDirection: "row-reverse",
  },

  buttonContainer: {
    alignItems: "center",
  },
  //Button
  loginButton: {
    flexDirection: "row",
    marginTop: hp(14),
    alignItems: "center",
    justifyContent: "center",
    borderRadius: 32.5,
    width: wp(78.3),
    height: hp(7.3),
    backgroundColor: "grey",
  },
  //Inputs
  emailInput: {
    height: hp(5.4),
    width: wp(65.2),
    borderBottomColor: "grey",
    borderBottomWidth: 1,
  },
  passwordInput: {
    height: hp(5.4),
    width: wp(65.2),
    marginTop: hp(6.3),
    borderBottomColor: "grey",
    borderBottomWidth: 1,
  },
  confirmPasswordInput: {
    height: hp(5.4),
    width: wp(65.2),
    marginTop: hp(6.3),
    borderBottomColor: "grey",
    borderBottomWidth: 1,
  },
  //Title
  title: {
    flex: 1,
    textAlign: "center",
    fontSize: hp(3.8),
  },
  //Loading
  preloader: {
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    position: "absolute",
    alignItems: "center",
    justifyContent: "center",
    backgroundColor: "#fff",
  },
  //Icons
  eyeIcon: {
    position: "absolute",
    paddingTop: 45,
  },
});

现在,我想创建一个执行以下操作的自定义输入组件:

  • 接收动态值(电子邮件/密码/...)
  • 接收动态占位符
  • 仍然可以在注册模块上的更改文本上调用我的updateInputVal函数
  • 如果当前textInput的值为密码,则在当前textInput内显示“一些图标”
  • 如果输入中的当前值不正确,请更改textInput边框颜色

我该如何处理?

1 个答案:

答案 0 :(得分:1)

首先创建输入组件。

Input.js

import React from 'react'
import { View, TextInput, StyleSheet, Text } from 'react-native' 
import { Ionicons } from '@expo/vector-icons';
const Input =  ({
    value,
    placeholder,
    onChangeText,
    onBlur,
    secureTextEntry,
    inputStyle,
    viewStyle,
    icon=false
  }) => {
    return (
      <View style={[styles.container, viewStyle]}>
        <TextInput
          style={[styles.main, inputStyle]}
          value={value}
          onChangeText={onChangeText}
          onBlur={onBlur}
          placeholder={placeholder}
          secureTextEntry={secureTextEntry}
        />
        {icon ? <Ionicons name="md-checkmark-circle" size={32} color="green" />: <View/>}
      </View>
    )
}

const styles = StyleSheet.create({
  container: {
      borderColor: 'black',
      borderWidth: 1,
      flexDirection: 'row',
      justifyContent: 'space-between'
  },
  main: {
    padding: 10
  }
})

export { Input }

在父级组件中使用

App.js

 import {Input} from './components/Input'

简单用法

<Input placeholder={'Dynamic placeholder'}/> 

具有价值

<Input placeholder={'Dynamic placeholder'} value={'your value email/password'}/>

隐藏文本并显示图标

<Input placeholder={'Dynamic placeholder'} 
       value={'your value email/password'}
       secureTextEntry
       icon/>

我想你明白了。我使用了expo作为图标。因此,如果您使用的是React Native CLI。使用适当的图标库。