React Native Plant App UI #8 : Sign Up Screen

This tutorial is the eighth part of our React Native Plant App tutorial series. In the previous part, we successfully implemented the different UI sections of the Forgot Password Screen. This tutorial is the continuation of the same tutorial from where we left off in the last part. So, it is recommended to go through the previous part in order to get insight and knowledge of the overall project.

In case of wanting to learn from the beginning, all the previous parts for this tutorial series are available below:

React Native Plant App UI #1: Getting Started
React Native Plant App UI #2: Implementing Custom Components
Building React Native Plant App UI #3: Implementing Welcome Screen
React Native Plant App UI #4: Illustration Slider and Animated Steps
React Native Plant App UI #5: Terms of Service Modal
Building React Native Plant App UI #6: Login Screen
React Native Plant App UI #7: Forgot Password Screen

As stated in the previous parts, the tutorial series was inspired by the React Native App Templates that provide a wide variety of mobile application templates written in React Native and powered by universal features and design. These app templates allow us to implement our own apps and even start our own startups. And, this eighth part is also the continuation of coding implementations and designs from the Youtube video tutorial by React UI Kitfor the Plant App. The video tutorial delivers the coding implementation of the overall app very thoroughly. However, there is no verbal guidance for coding and implementation. Hence, this tutorial series is the implementation of the same coding style and designs in the form of the article. Thus, the learners can go through each step and take their time understanding the implementations.

Overview

In this eighth part of this tutorial series, we are going to implement the Sign-Up Screen with different UI sections. The Sign-Up screen will be more or less similar to the Login Screen or Forgot Password as well. The UI sections are very much similar to that of the Login Screen. This screen will contain comparatively more input fields which is the only difference in terms of UI of different screens. We will also implement the error handling as well as the loading state at the end.

So, let us begin!!

Implementing Sign-Up Screen

We have already set up the simple React Native template in the Signup.js screen file. And, we have also set up the navigation configuration from the Login screen to the Sign-Up screen. Here, we are going to implement the different UI sections of the Sign-Up Screen. This screen is more or less similar to Login Screen. So, we are going to copy some of the codes from our Login screen to the Sign-Up screen. First, we are going to import the necessary components as shown in the code snippet below:

import { Alert, ActivityIndicator, Keyboard, KeyboardAvoidingView, StyleSheet } from 'react-native';
import { Button, Block, Input, Text } from '../components';
import { theme } from '../constants';

Here, we have imported the required components to build this screen from the react-native package. Then, we have also imported with the predefined custom components from our ‘./components/’ folder. The theme module is also imported from the ‘./constants/’. Now, we are going to define and initialize the required state variables as shown in the code snippet below:

state = {
    email: null,
    username: null,
    password: null,
    errors: [],
    loading: false,
  }

Here, we have defined the emailusernamepassword state variables and is set to the null value, errors array and loading state as false.

Adding Header and Input Section

Note that we need to remember to remove the navigationOptions config as well. Here, we are going to add the header section as well as the input field. This screen will contain three input fields for entering the email, username, and password. The styles of the input field will be similar to that in the Login screen. Now, in order to implement these sections, we need to make use of the code from the following code snippet in the render() function of Signup.js file:

render(){
    return (
      <KeyboardAvoidingView style={styles.signup} behavior="padding">
        <Block padding={[0, theme.sizes.base * 2]}>
          <Text h1 bold>Sign Up</Text>
          <Block middle>
          <Input
              email
              label="Email"
              style={[styles.input]}
              defaultValue={this.state.email}
              onChangeText={text => this.setState({ email: text })}
            />
            <Input
              label="Username"
              style={[styles.input]}
              defaultValue={this.state.username}
              onChangeText={text => this.setState({ username: text })}
            />
            <Input
              secure
              label="Password"
              style={[styles.input]}
              defaultValue={this.state.password}
              onChangeText={text => this.setState({ password: text })}
            />
          </Block>
        </Block>
      </KeyboardAvoidingView>

    );
  }

Here, we have used the KeyboardAvoidingView as the parent component. This component helps to shift the content inside it shift above the keyboard when the actual keyboard is triggered in the app. Then, we have the Block component wrapping the Text component and another child Block component. The child Block component wraps the Input component for our email, username, and password entries. The Input component has some props from the label and defaultValue. We receive the value of email, username, and password by changing the there state values in the onChangeText event. There are some styles configured to the components as well which is provided in the code snippet below:

signup: {
  flex: 1,
  justifyContent: 'center',
},
input: {
  borderRadius: 0,
  borderWidth: 0,
  borderBottomColor: theme.colors.gray2,
  borderBottomWidth: StyleSheet.hairlineWidth,
},
hasErrors: {
  borderBottomColor: theme.colors.accent,
}


Hence, we will get the following result in our emulator screen:As we can see, we have got the Header as well as the input fields in our Sign-Up screen. And, when the keyboard is triggered by tapping on any input fields, all the Input components are shifted up to avoid blockage from the inputs from the keyboard.

Adding Buttons

In this step, we are going to add buttons to the Sign-Up screen. We are going to add two buttons. One is the Sign-Up button and another is navigation back to the Login Screen button. This button will be placed below the input fields. In order to add buttons, we need to use the code from the following code snippet:

<Block middle>
    <Input
        email
        label="Email"
        style={[styles.input]}
        defaultValue={this.state.email}
        onChangeText={text => this.setState({ email: text })}
      />
      <Input
        label="Username"
        style={[styles.input]}
        defaultValue={this.state.username}
        onChangeText={text => this.setState({ username: text })}
      />
      <Input
        secure
        label="Password"
        style={[styles.input]}
        defaultValue={this.state.password}
        onChangeText={text => this.setState({ password: text })}
      />
      <Button gradient onPress={() => this.handleSignUp()}>
        {loading ?
          <ActivityIndicator size="small" color="white" /> :
          <Text bold white center>Sign Up</Text>
        }
      </Button>
      <Button onPress={() => navigation.navigate('Welcome ')}>
        <Text gray caption center style={{ textDecorationLine: 'underline' }}>
          Back to Login
        </Text>
      </Button>
    </Block>

Here, we have used the Button component. The Button component with some style props wraps the Text component in order to display text inside the button. The Back to Login button has the navigation configured to its onPress event. Hence, we will get the following result in our emulator screen:As we can see, we have the required buttons on the Sign-Up screen. Taping on the Back to Login button enables us to navigate back to the Login screen.

Configuring the Sign-Up button

As we might have seen that, we have called the handleSignUp() function in the onPress event of the Sign-Up button. But, we still have not defined any sort of function named handleSignUp(). Here, we are going to defined and configure the handleSignUp()function. Now, in the handleSignUp() function, we need to check the email, username, and password for errors. We are also going to configure the loading state by changing the states of the loading state before and after the successful signing up. For that, we need to use the code from the following code snippet:

handleSignUp() {
    const { navigation } = this.props;
    const { email, username, password } = this.state;
    const errors = [];
    Keyboard.dismiss();
    this.setState({ loading: true });
    // check with backend API or with some static data
    if (!email) errors.push('email');
    if (!username) errors.push('username');
    if (!password) errors.push('password');
    this.setState({ errors, loading: false });
    if (!errors.length) {
      Alert.alert(
        'Success!',
        'Your account has been created',
        [
          {
            text: 'Continue', onPress: () => {
              navigation.navigate('Browse')
            }
          }
        ],
        { cancelable: false }
      )
    }
  }

Here, we have also used the dismiss() function of the Keyboard component in order to hide the keyboard when we press the Sign-Up button. Then, on the basis of the value of the emailusername and password, we have pushed the errors in the errors array. Then, on the basis of the length of errors array we have shown in the sign-up success alert.

Handling errors

Now, we need to show some sort of style change when the wrong email is entered. First, we need to import the state variables in the render() function as shown in the code snippet below:

render() {
    const { navigation } = this.props;
    const { loading, errors } = this.state;
    const hasErrors = key => errors.includes(key) ? styles.hasErrors : null;

Here, we have imported the loading and errors states. Then, we have defined a new function called hasErrors() and it returns the value depending on the key value of the errors state array. Now, we are going to change the style of the input field in order to show the error. For that, we need to use code from the following code snippet:

<Input
  email
  label="Email"
  error={hasErrors('email')}
  style={[styles.input, hasErrors('email')]}
  defaultValue={this.state.email}
  onChangeText={text => this.setState({ email: text })}
/>
<Input
  label="Username"
  error={hasErrors('username')}
  style={[styles.input, hasErrors('username')]}
  defaultValue={this.state.username}
  onChangeText={text => this.setState({ username: text })}
/>
<Input
  secure
  label="Password"
  error={hasErrors('password')}
  style={[styles.input, hasErrors('password')]}
  defaultValue={this.state.password}
  onChangeText={text => this.setState({ password: text })}
/>

Here, we have added the error prop to the Input components which call the hasError() function with specific parameters Then, we have also added the error style which is provided in the code snippet below:

hasErrors: {
    borderBottomColor: theme.colors.accent,
  }

Hence, we will get the following result in the emulator screen:As we can see, when we enter all the inputs correctly, the sign-up success alert is shown on the screen.

And when we tap the ‘Continue’ button on the alert message, we should navigate to the Browse screen. But, navigation to Browse screen does not work because we have not removed the comment from the Browse screen in the index.js file of the ‘./navigation/’ folder. And we have not implemented it as well.

Now, we need to test the errors which are shown in the emulator simulation below:

As we can see, if we do not enter any of the input, we get the error style in the respective input field.

We can set the setTimeout function in order to display the loading state just as in the Login screen. In the real scenario, when we are requesting some data from the server, it will automatically show up. With this, we have come to the end of this part of the tutorial.

Finally, we have successfully completed the implementation of the Sign-Up Screen in our React Native Plant UI App.

Conclusion

This tutorial is the eighth part of the React Native Plant App UI tutorial series. In this part, we continued from where we left off in the seventh part of this tutorial series. In this part of the tutorial, we got stepwise guidance on how to use different custom components to implement the overall UI of the Sign-Up screen. This Screen implementation is similar to that of the Login Screen from our previous tutorial part. Lastly, we also learned how to handle the errors and show the success alert messages.

In the next part of this tutorial series, we are going to start implementing different UI sections of our Browse screen.