DEV Community

Cover image for Building Multi-page Signup Login React Native App Part 2
Pratik280
Pratik280

Posted on • Updated on • Originally published at pratik280.github.io

Building Multi-page Signup Login React Native App Part 2

Introduction

In this second part of our multi-part series, we will continue building our multi-page signup/login app in React Native. In this blog, we will cover the following topics:

  1. Styling components using TailwindCSS
  2. Creating individual React Native components with the ability to pass props.

You can find the source code on my Github.

Disclaimer: This project is UI-focused, with an emphasis on styling and design. It's a mobile app, but it's not connected to any backend or database, so all the data is hard-coded in the pages. The primary goal of this project is to practice coding and explore various design ideas, with the aim of producing a visually appealing and functional mobile app.

Few steps to follow before we start.

  1. To keep our reusable React Native components in an organized manner, let's create a folder named components.
  2. You can create a folder named assets to store images, SVGs, and other static resources that are required in your React Native app.

Design System (colors)

We are going to use the following colors:

  1. For Backgroud: #fff ie white in tailwindcss
  2. For dark text: '#3F3D56'
  3. For white text: '#f3f4f6'
  4. Primary Color: '#8B5CF6' ie blue-500 in tailwindcss
  5. bgGray: '#e4e4e7'

To use colors more conveniently in Tailwind CSS classes, we can add them to the Tailwind config file:

tailwind.config.js

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./App.{js,jsx,ts,tsx}",
    "./components/*.{js,jsx,ts,tsx}",
    "./pages/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {
      colors: {
        textDark: "#3F3D56",
      },
    },
  },
  plugins: [],
};
Enter fullscreen mode Exit fullscreen mode

To ensure that we can apply Tailwind CSS to the components that will be present inside the components directory, we have included this directory in the content section of the Tailwind CSS configuration file.

To style components using props, we will also use React Native Stylesheet. To define all the necessary color values, we will create a colors.js file in the assets/folder.

assets/colors.js

export default {
  textDark: "#3F3D56",
  textWhite: "#f3f4f6",
  primary: "#8B5CF6",
  bgGray: "#e4e4e7",
};
Enter fullscreen mode Exit fullscreen mode

Creating Heading Component.

Creating a Header Text that will be visible on all the pages.

Greeting.tsx

<Text className="text-textDark text-4xl font-extrabold">CodeGenius</Text>
Enter fullscreen mode Exit fullscreen mode

To ensure reusability of the Heading component across all pages, it is best practice to create a separate component file for it.

Create a Heading component components/Heading.tsx.

import { Text } from "react-native";
import React from "react";

export default function Heading(props) {
  return (
    <Text className="text-textDark text-4xl font-extrabold">
      {props.content}
    </Text>
  );
}
Enter fullscreen mode Exit fullscreen mode

We will make the Heading component reusable by passing text as a prop, enabling us to use the same component for displaying headings with different text.

We will import the reusable Heading component in pages/Greeting.tsx and pass the content prop to it, as shown below:

import Heading from "../components/Heading";

const Greeting = ({ navigation }) => {
  return (
    <SafeAreaView className="bg-white container h-full px-7">
      <Heading content="CodeGenius" />

      <View className="mt-6">
        <TouchableOpacity
          className="mt-3 rounded-xl py-3"
          style={{ elevation: 1, backgroundColor: colors.primary }}
          onPress={() => navigation.navigate("Login")}
        >
          <Text
            className="text-center text-base"
            style={{ color: colors.textWhite }}
          >
            Login
          </Text>
        </TouchableOpacity>
        <CustomButton
          navigation={navigation}
          bgColor={colors.bgGray}
          textColor={colors.textDark}
          goto={"Signup"}
          content={"Singup"}
        />
      </View>
    </SafeAreaView>
  );
};
Enter fullscreen mode Exit fullscreen mode

This is how our application looks now:

Fig. 1 - Heading Component

Hero image

While there are plenty of image and vector art resources available online, we'll be using an image from undraw for this demonstration. First, download the image and save it in the assets folder of your project. Then, follow these steps to add the vector art to your project.

pages/Greeting.tsx

      <View className="flex justify-center items-center mt-24">
        <Image
          source={require('./../assets/hero.png')}
          style={{width: 400, height: 300}}
        />
      </View>
      <Heading content="CodeGenius" />
Enter fullscreen mode Exit fullscreen mode

Fig. 2 - Hero Component

Buttons

Writing code for resusable button component.
The CustomButton component in our code has been designed to be reusable in different ways. We can customize the button's appearance and functionality by passing values to different props. For example, we can use the "navigation" prop to navigate to a different page, set the background color with "bgColor" prop, set the text color with "textColor" prop, set the text content with "content" prop, and set the navigation destination with "goto" prop. By using these different props in different combinations, we can create a CustomButton component that meets our specific requirements. This allows us to create buttons quickly and efficiently for various parts of our application without having to write new code each time.

compnents/CustomButton.tsx

import { TouchableOpacity, Text } from "react-native";
import React from "react";

const CustomButton = props => {
  return (
    <TouchableOpacity
      className="mt-3 rounded-xl py-3"
      style={{ elevation: 1, backgroundColor: props.bgColor }}
      onPress={() => props.navigation.navigate(props.goto)}
    >
      <Text
        className="text-center text-base"
        style={{ color: props.textColor }}
      >
        {props.content}
      </Text>
    </TouchableOpacity>
  );
};

export default CustomButton;
Enter fullscreen mode Exit fullscreen mode

With the reusable CustomButton component we have created, we can create multiple buttons with different colors and text using props. By passing different values to the bgColor and textColor props, we can create buttons with different color schemes. Additionally, we can change the text displayed on the button by passing the desired text to the content prop. We can also use the goto prop to specify the page that the button should navigate to when it is clicked. By utilizing these props in different combinations, we can create custom buttons according to our needs.

<CustomButton
  navigation={navigation}
  bgColor={'#f87171'}
  textColor={'#fff'}
  goto={'Signup'}
  content={'Hello'}
/>
<CustomButton
  navigation={navigation}
  bgColor={'#059669'}
  textColor={'#fff'}
  goto={'Signup'}
  content={'Click Here'}
/>
<CustomButton
  navigation={navigation}
  bgColor={colors.primary}
  textColor={colors.textWhite}
  goto={'Login'}
  content={'Login'}
/>
<CustomButton
  navigation={navigation}
  bgColor={colors.bgGray}
  textColor={colors.textDark}
  goto={'Signup'}
  content={'Singup'}
/>
Enter fullscreen mode Exit fullscreen mode

Fig. 3 - Buttons

Form elements

In this section, we will be styling a form that includes the following elements:

  1. Text inputs for entering first name, last name, email, and password.
  2. A signup button to create a new account.
  3. Google and Facebook buttons to login with those accounts.
  4. A link to the login page for users who already have an account.

The form will provide a simple and user-friendly way for users to sign up for our service and log in using their preferred method. By incorporating popular social media platforms, we can make the process more convenient for users and potentially attract more users to our platform. The text inputs will allow users to provide their basic information securely, and the signup button will complete the registration process. If users already have an account, they can easily access it through the login page linked in the form.

Text inputs

Creating a text input for First Name. We will use useState hook which is a built-in hook in React/Reat-Native that allows functional components to have state variables and update them. It takes an initial value and returns an array with two elements: the current state value and a function to update it. This means that you can update the data within your component and React will automatically re-render the component to reflect the changes.

pages/Signup.tsx

const [firstName, setFirstName] = useState("");
Enter fullscreen mode Exit fullscreen mode

The TextInput component is used to take input from keyboard in react native.

<TextInput
  onChangeText={setFirstName}
  placeholder={"First Name"}
  placeholderTextColor={colors.textDark}
  value={firstName}
  className="bg-zinc-200 text-textgray rounded-xl py-3 px-5"
/>
Enter fullscreen mode Exit fullscreen mode

When the user types something into the input field, the setFirstName function is called with the new value as an argument, and the firstName state variable is updated with that value. The placeholder prop sets the initial text displayed in the input field, while the value prop sets the current value of the input field. The className prop sets the CSS classes used for styling the input field, in this case a light gray background, dark text, and rounded corners.

In the same way we can create multiple text inputs like Last Name, Email and password.

Social buttons

Creating a functional component called "SocialIcons" that displays two TouchableOpacity buttons with Google and Facebook logos as images.

components/SocialIcons.tsx

import { View, TouchableOpacity, Image } from "react-native";
import React from "react";

const SocialIcons = () => {
  return (
    <View className="flex flex-row items-center justify-center">
      <TouchableOpacity className="bg-zinc-200 mx-2 rounded-lg px-16 py-2">
        <Image
          source={require("./../assets/google.png")}
          style={{ width: 30, height: 30 }}
        />
      </TouchableOpacity>
      <TouchableOpacity className="bg-zinc-200 mx-2 rounded-lg px-16 py-2">
        <Image
          source={require("./../assets/facebook.png")}
          style={{ width: 30, height: 30 }}
        />
      </TouchableOpacity>
    </View>
  );
};

export default SocialIcons;
Enter fullscreen mode Exit fullscreen mode

Complete Signup Page Code

pages/Signup.tsx

import { View, Text, TouchableOpacity, TextInput } from "react-native";
import { useState } from "react";
import { SafeAreaView } from "react-native-safe-area-context";
import Heading from "../components/Heading";
import CustomButton from "../components/CustomButton";
import colors from "../assets/colors";
import SocialIcons from "../components/SocialIcons";

const Signup = ({ navigation }) => {
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  return (
    <SafeAreaView className="bg-white container h-full px-7">
      <View className="mt-24">
        <Heading content="Create Account" />
      </View>
      <View className="mt-4">
        <TextInput
          onChangeText={setFirstName}
          placeholder={"First Name"}
          placeholderTextColor={colors.textDark}
          value={firstName}
          className="bg-zinc-200 text-textgray rounded-xl py-3 px-5"
        />
        <TextInput
          onChangeText={setLastName}
          placeholder={"Last Name"}
          placeholderTextColor={colors.textDark}
          value={lastName}
          className="bg-zinc-200 text-textgray mt-3 rounded-xl py-3 px-5"
          // style={{color: '#000000'}}
        />
        <TextInput
          onChangeText={setEmail}
          placeholder={"Email"}
          placeholderTextColor={colors.textDark}
          value={email}
          className="bg-zinc-200 text-textgray mt-3 rounded-xl py-3 px-5"
        />
        <TextInput
          secureTextEntry={true}
          onChangeText={setPassword}
          placeholder={"Password"}
          placeholderTextColor={colors.textDark}
          value={password}
          className="bg-zinc-200 text-textgray mt-3 rounded-xl py-3 px-5"
        />
        <TouchableOpacity
          className="mt-2 flex items-end"
          onPress={() => navigation.goBack()}
        >
          <Text className="text-textgray font-bold">Forgot Password?</Text>
        </TouchableOpacity>
      </View>
      <CustomButton
        navigation={navigation}
        bgColor={colors.primary}
        textColor={colors.textWhite}
        goto={"Items"}
        content={"Signup"}
      />
      <View className="mt-10">
        <Text className="text-textgray text-center">Or Continue With</Text>
        <View className="mt-2">
          <SocialIcons />
        </View>
        <View className="mt-24 flex flex-row items-center justify-center">
          <Text className="text-textgray">Already have a accout?</Text>
          <TouchableOpacity onPress={() => navigation.navigate("Login")}>
            <Text className="text-textgray underline">Login</Text>
          </TouchableOpacity>
        </View>
      </View>
    </SafeAreaView>
  );
};

export default Signup;
Enter fullscreen mode Exit fullscreen mode

Fig. 4 - Signup Page

Login Page

Similary create Login page

pages/Login.tsx

import { View, Text, TouchableOpacity, TextInput, Image } from "react-native";
import { useState } from "react";
import { SafeAreaView } from "react-native-safe-area-context";
import Heading from "../components/Heading";
import CustomButton from "../components/CustomButton";
import colors from "../assets/colors";
import SocialIcons from "../components/SocialIcons";

const Login = ({ navigation }) => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  return (
    <SafeAreaView className="bg-white container h-full px-7">
      <View className="mt-36">
        <Heading content="Welcome Back" />
      </View>
      <View className="mt-4">
        <TextInput
          onChangeText={setEmail}
          placeholder={"Email"}
          placeholderTextColor={colors.textDark}
          value={email}
          className="bg-zinc-200 rounded-xl py-3 pl-5"
        />
        <TextInput
          secureTextEntry={true}
          onChangeText={setPassword}
          placeholder={"Password"}
          placeholderTextColor={colors.textDark}
          value={password}
          className="bg-zinc-200 mt-3 rounded-xl py-3 pl-5"
        />
        <TouchableOpacity
          className="mt-2 flex items-end"
          onPress={() => navigation.goBack()}
        >
          <Text className="text-textDark font-bold">Forgot Password?</Text>
        </TouchableOpacity>
      </View>
      <CustomButton
        navigation={navigation}
        bgColor={colors.primary}
        textColor={colors.textWhite}
        goto={"Items"}
        content={"Login"}
      />
      <View className="mt-10">
        <Text className="text-textDark text-center">Or Continue With</Text>
        <View className="mt-2">
          <SocialIcons />
        </View>
        <View className="mt-44 flex flex-row items-center justify-center">
          <Text className="text-textDark">Does'nt have a accout?</Text>
          <TouchableOpacity onPress={() => navigation.navigate("Signup")}>
            <Text className="text-textDark underline">Signup</Text>
          </TouchableOpacity>
        </View>
      </View>
    </SafeAreaView>
  );
};

export default Login;
Enter fullscreen mode Exit fullscreen mode

Fig. 5 - Login Page

Conclusion

In conclusion, building a UI for a login and signup form in React Native using TailwindCSS and functional reusable components can help streamline the development process and improve the overall user experience. By leveraging the power of React Native and the flexibility of TailwindCSS, we can create stunning UIs with minimal effort, while also maintaining a high degree of customization and flexibility. Additionally, the use of functional reusable components allows developers to create modular, reusable code that can be easily scaled and adapted for future projects. Overall, the process of building a login and signup form UI in React Native with TailwindCSS is a powerful and efficient way to create sleek and user-friendly interfaces for any mobile app.

Top comments (0)