Building a Finance Management App with React Native - Part 3

Implementing the Sign-Up Process

In this step, I check the different inputs and only let the user move on to the next page if all the checks pass.

First, I initialize the variables to be used to register the user (email, full name, password, and confirm password). - used the react usestate hook. It enables us use state within a function component. It will keep track of the variables. Any time the value of the variable is changed the hook will update the value of the variable. Set all the variables to an empty string. Each variable is set alongside its setting function.

Initialise the error messages as well for each of the variables using the react usestate hook. Set them to null.

//initiliaze formdata variables
  const [email, setEmail] = React.useState("");
  const [fullName, setFullName] = React.useState("");
  const [password, setPassword] = React.useState("");
  const [confirmPass, setConfirmPass] = React.useState("");
  //initialise error messages
  const [emailErr, setEmailErr] = React.useState(null);
  const [fullNameErr, setFullNameErr] = React.useState(null);
  const [passwordErr, setPasswordErr] = React.useState(null);
  const [confirmPassErr, setConfirmPassErr] = React.useState(null);

Pass the variables and their set functions and the respective error messages to the respective screens as props. Receive them on each of the screens and set them as the value of the text input, set the onChangeText function to change the value of the variable. Conditionally render the error message to only show if the value is not null.

Put the text-inputs within a keyboard avoiding view to prevent the keyboard from hiding the text-input when the user clicks on the text-input.

Create a function on each of the screens to validate the data on each screen.

ScreenTwo.js

This screen has the Name input. Validation tests for the name input:

  • If it is empty

  • If it is too short

export default function ScreenTwo({
  fullName,
  setFullName,
  fullNameErr,
  setFullNameErr,
}) {
  const validateData = () => {    
    //check if it is empty
    if (fullName === "") {
      setFullNameErr("Name is required");
      return;
    }
    //check length of name - should be at least 3 characters
    if (fullName.length < 3) {
      setFullNameErr(
        "Name is too short. - It should be at least 3 characters."
      );
      return;
    }
  };
  return (
    <KeyboardAvoidingView style={styles.container} behavior="padding">
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View>
          <Image
            source={require("../../assets/img/onb.png")}
            style={styles.onbImg}
          />
          <Text style={[styles.heading]}>Tell us your name</Text>
          <TextInput
            label="Name"
            variant="outlined"
            style={styles.textInput}
            value={fullName}
            onChangeText={(fullName) => setFullName(fullName)}
          />
          {/* conditionally render the error message */}
          {fullNameErr && <Text style={styles.errorTxt}>{fullNameErr}</Text>}
          <View style={styles.row}>
            <TouchableOpacity style={styles.button} onPress={validateData}>
              <LongButton text="Save" />
            </TouchableOpacity>
          </View>
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
}

Screen-Three.js

The email address is entered on this screen. Validations for the email input:

  • If it is an empty string

  • If it is a valid email - To check for validity, we use the email regex pattern and use the Javascript check method. The check method receives a string and checks if it matches the regex given. It then returns true if the string matches and false if it does not.

The code is as follows:

export default function ScreenThree({
  email,
  setEmail,
  emailErr,
  setEmailErr,
}) {
  const validateData = () => {
    let validEmail = /\S+@\S+\.\S+/.test(email);    
    //check if it is empty
    if (email === "") {
      setemailErr("Email is required");
      return;
    }
    //check if it is a valid email
    if (!validEmail) {
      setEmailErr(
        "The email is invalid"
      );
      return;
    }
  };
  return (
    <KeyboardAvoidingView style={styles.container} behavior="padding">
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View>
          <Image
            source={require("../../assets/img/onb.png")}
            style={styles.onbImg}
          />
          <Text style={[styles.heading]}>Tell us your email</Text>
          <TextInput
            label="Email"
            variant="outlined"
            style={styles.textInput}
            value={email}
            onChangeText={(email) => setEmail(email)}
          />
          {/* conditionally render the error message */}
          {emailErr && <Text style={styles.errorTxt}>{emailErr}</Text>}
          <View style={styles.row}>
            <TouchableOpacity style={styles.button} onPress={validateData}>
              <LongButton text="Save" />
            </TouchableOpacity>
          </View>
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
}

Screen-Four.js

This screen has the password and confirm password inputs. The validations for these inputs are as follows:

  • If the password is an empty string

  • If the passwords match

  • If the password is strong - To check if it is a strong password, we'll use a regex pattern to check the length, and if it contains alphanumeric.

The code is as follows:

export default function ScreenFour(
  password,
  setPassword,
  confirmPass,
  setConfirmPass,
  confirmPassErr,
  setConfirmPassErr,
  passwordErr,
  setPasswordErr
) {
  const validateData = () => {
    let strongPassword =
      /(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.{10,})/.test(
        password
      );
    //password is empty
    if (password === "") {
      setPasswordErr("Password is required.");
      return;
    }
    //check if passwords match
    if (password !== confirmPass) {
      //setConfirmPassErr("Passwords do not match.");
      return;
    }
    //check if it is a strong password
    if (!strongPassword) {
      setPasswordErr(
        "Weak Password. Ensure it is more than 10 characters and has alphanumeric characters."
      );
      return;
    }
  };
  return (
    <View style={styles.container}>
      <Image
        source={require("../../assets/img/onb.png")}
        style={styles.onbImg}
      />
      <Text style={[styles.heading]}>Set a Password</Text>
      <TextInput
        label="Password"
        variant="outlined"
        style={styles.textInput}
        value={password}
        onChangeText={(password) => setPassword(password)}
      />
      {/* conditionally render the error message */}
      {passwordErr && <Text style={styles.errorTxt}>{passwordErr}</Text>}
      <TextInput
        label="Confirm Password"
        variant="outlined"
        style={styles.textInput}
        value={confirmPass}
        onChangeText={(confirmPass) => setConfirmPass(confirmPass)}
      />
      {/* conditionally render the error message */}
      {confirmPassErr && <Text style={styles.errorTxt}>{confirmPassErr}</Text>}

      <View style={styles.row}>
        <TouchableOpacity style={styles.button} onPress={validateData}>
          <LongButton text="Done" />
        </TouchableOpacity>
      </View>
    </View>
  );
}

All the validation checks are done, and the next step is to design and implement the home page.