React-Native表单验证

时间:2017-07-17 18:25:41

标签: reactjs react-native

进行表单验证的最佳方法是哪种。我目前正在使用native-base,我需要显示userName和password的内联消息。例如:'用户名是必需的'或者'密码是必需的'

以下代码表示表单视图。

import React, { Component } from 'react';
import {
  Alert,
  Text,
  TextInput,
  TouchableOpacity,
  View,
  AsyncStorage,
  StyleSheet,
  Image
} from 'react-native';

import { Item, Label, Input } from 'native-base';

import { Actions } from 'react-native-router-flux';

export default class Login extends Component {

  constructor() {
    super();
    this.state = { 
      username: null,
      password: null,
      versionNumber:'N/A' };
  }

  async saveItem(item, selectedValue) {
    try {
      await AsyncStorage.setItem(item, selectedValue);
    } catch (error) {
      console.error('AsyncStorage error: ' + error.message);
    }
  }

  userLogin() {
    if (!this.state.username || !this.state.password) return;

    fetch('https://mobiletest.myapp.com/api/auth', {
      method: 'POST',
      headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
      body: JSON.stringify({
        username: this.state.username,
        password: this.state.password
      })
    })
      .then((response) => response.json())
      .then((responseData) => {
        this.saveItem('id_token', responseData.userId);
        Alert.alert('Login Success!');
        Actions.InspectionListGenerator();
      })
      .done();
  }

  render() {
    return (
      <BackgroundImage>
        <View style={styles.container}>
          <View>
            <Image style={styles.logo} resizeMode='contain' source={require('../assets/images/logo.png')} />
          </View>
          <Text style={styles.transformDataTitle}> Data</Text>
          <Text style={styles.transformDataSubTitle}>  Asset Management</Text>
          <View style={styles.form}>

             <Item floatingLabel style={StyleSheet.flatten(styles.floatingLabel)}>
              <Label>Username</Label>
                 <Input 
                         autoCapitalize="none"
                         onChangeText={(text) => this.setState({username: text})}
                         value={this.state.username}
                     />

            </Item>

            <Item floatingLabel style={StyleSheet.flatten(styles.floatingLabel)}>
              <Label>Password</Label>
              <Input 
                         onChangeText={(text) => this.setState({password: text})}
                         value={this.state.password}
                         secureTextEntry={true}
                     />

            </Item>

            <TouchableOpacity style={styles.buttonWrapper} onPress={this.userLogin.bind(this)}>
              <Text style={styles.buttonText}> LOGIN </Text>
            </TouchableOpacity>

            <Text style={styles.forgotYourPassword}>FORGOT YOUR PASSWORD?</Text>

            <Text style={styles.versionNumber}>v N/A</Text>
          </View>
        </View>
      </BackgroundImage>
    );
  }
}

class BackgroundImage extends Component {

  render() {
    return (
      <Image source={require('../assets/images/login-bg.png')}
        style={styles.backgroundImage}>

        {this.props.children}

      </Image>
    )
  }
}

const styles = StyleSheet.create({
  backgroundImage: {
    flex: 1,
    width: null,
    height: null,
    resizeMode: 'cover'
  },
  logo: {
    flex: 1,
    aspectRatio: 8,
    resizeMode: 'contain'
  },
  buttonText: {
    fontSize: 16,
    padding: 10,
    textAlign: 'center',
    color: '#ffffff'
  },
  buttonWrapper: {
    backgroundColor: '#054e6e',
    marginBottom: 10,
    marginTop: 10,
    width: 300
  },
  container: {
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center'
  },
  form: {
    width: 300,
    marginTop: 20
  },
  image: {
    margin: 10
  },
  floatingLabel:{
    backgroundColor: 'white'
  },
  transformDataTitle: {
    fontSize: 35,
    margin: 10,
    textAlign: 'center',
    color: 'white',
    fontFamily: "oxygen-regular"
  },
  transformDataSubTitle: {
    fontSize: 12,
    textAlign: 'center',
    color: 'white',
    fontFamily: "oxygen-regular"
  },
  forgotYourPassword:{
    marginTop: 20,
    textAlign: 'center',
    color: '#054e6e'
  },
  versionNumber:{
    marginTop: 20,
    textAlign: 'center',
    color: 'white'
  }
});

1 个答案:

答案 0 :(得分:3)

如果您不使用Redux,可以在状态中添加两个参数,一个名为hasError,这是一个布尔值,告诉我们表单中是否有错误,另一个名为errorMessage,其中包含要显示的错误消息。

this.state = { 
      username: null,
      password: null,
      versionNumber:'N/A',
      hasError: false,
      errorMessage: ''
};

然后当用户提交时,您需要检查每个输入是否正确,如果不是,则需要将状态设置为:hasError = true和errorMessage =错误消息 例如:

if(this.state.username.length<=3)
   this.setState({hasError: true, errorMessage: "Username need to be longer than 3 characters");

然后在表单的底部,您可以添加一个红色的文本,如果有的话会显示错误文本,例如

{this.state.hasError ? <p>this.state.errorMessage</p> : null}

当用户更改输入内容时,请不要忘记将其设置为false。

除非将this.state.hasError或用于检查错误的任何变量设置为false,否则也不会发送HTTP请求。