
React Native Expo Tutorial #3 | Ecommerce App - Sign In & Sign Up Screens
we created user screen and added to our tab layout and created sign in, sign up, forgot password and otp components.

You can also watch the YouTube video:
React Native Expo Tutorial #3 | Ecommerce App - Sign In & Sign Up Screens
Installing Gluestack UI Components
npx gluestack-ui add form-control input
Let's edit the TabLayout app/(tabs)/_layout.tsx
file:
import { Icon } from "@/components/ui/icon";
import { Tabs } from "expo-router";
import { Home, ShoppingCart, User } from "lucide-react-native";
const TabLayout = () => {
return (
<Tabs screenOptions={{ tabBarActiveTintColor: "blue" }}>
<Tabs.Screen
name="index"
options={{
title: "Home",
tabBarIcon: () => <Icon as={Home} />,
}}
/>
<Tabs.Screen
name="cart"
options={{
title: "Cart",
tabBarIcon: () => <Icon as={ShoppingCart} />,
}}
/>
<Tabs.Screen
name="user"
options={{
title: "User",
tabBarIcon: () => <Icon as={User} />,
}}
/>
</Tabs>
);
};
export default TabLayout;
app/(tabs)
folder
Creating user.tsx file in import ForgotPassword from "@/components/ForgotPassword";
import OTP from "@/components/OTP";
import SignIn from "@/components/SignIn";
import SignUp from "@/components/SignUp";
import { Box } from "@/components/ui/box";
import { useState } from "react";
const UserScreen = () => {
const [currentComponent, setCurrentComponent] = useState("SignIn");
return (
<Box className="flex-1 p-8 bg-white">
{currentComponent === "SignIn" ? (
<SignIn setCurrentComponent={setCurrentComponent} />
) : undefined}
{currentComponent === "SignUp" ? (
<SignUp setCurrentComponent={setCurrentComponent} />
) : undefined}
{currentComponent === "ForgotPassword" ? (
<ForgotPassword setCurrentComponent={setCurrentComponent} />
) : undefined}
{currentComponent === "OTP" ? (
<OTP setCurrentComponent={setCurrentComponent} />
) : undefined}
</Box>
);
};
export default UserScreen;
Creating SignIn and SignUp Components
Create SignIn.tsx
in components
folder:
import { Button, ButtonText } from "@/components/ui/button";
import { FormControl } from "@/components/ui/form-control";
import { Heading } from "@/components/ui/heading";
import { Input, InputField, InputIcon, InputSlot } from "@/components/ui/input";
import { Text } from "@/components/ui/text";
import { VStack } from "@/components/ui/vstack";
import { EyeIcon, EyeOffIcon } from "lucide-react-native";
import { useState } from "react";
import { Box } from "./ui/box";
import { Pressable } from "react-native";
interface ISignIn {
setCurrentComponent: React.Dispatch<React.SetStateAction<string>>;
}
const SignIn: React.FC<ISignIn> = ({ setCurrentComponent }) => {
const [showPassword, setShowPassword] = useState(false);
const handleState = () => {
setShowPassword((showState) => {
return !showState;
});
};
return (
<FormControl className="p-4 border rounded-lg border-outline-300">
<VStack space="xl">
<Heading className="text-typography-900 leading-2">Sign In</Heading>
<VStack space="xs">
<Text className="text-typography-500 leading-1">Email</Text>
<Input>
<InputField type="text" />
</Input>
</VStack>
<VStack space="xs">
<Text className="text-typography-500 leading-1">Password</Text>
<Input className="text-center">
<InputField type={showPassword ? "text" : "password"} />
<InputSlot className="pr-3" onPress={handleState}>
{/* EyeIcon, EyeOffIcon are both imported from 'lucide-react-native' */}
<InputIcon
as={showPassword ? EyeIcon : EyeOffIcon}
className="text-blue-500"
/>
</InputSlot>
</Input>
<Box className="flex flex-row items-center justify-between mt-2">
<Pressable onPress={() => setCurrentComponent("SignUp")}>
<Text className="text-blue-500">Sign Up</Text>
</Pressable>
<Pressable onPress={() => setCurrentComponent("ForgotPassword")}>
<Text className="text-blue-500">Forgot Password?</Text>
</Pressable>
</Box>
</VStack>
<Button
className="bg-blue-500"
onPress={() => setCurrentComponent("OTP")}
>
<ButtonText className="text-typography-0 text-center flex-1">
Sign In
</ButtonText>
</Button>
</VStack>
</FormControl>
);
};
export default SignIn;
Create SignUp.tsx
in components
folder:
import { Button, ButtonText } from "@/components/ui/button";
import { FormControl } from "@/components/ui/form-control";
import { Heading } from "@/components/ui/heading";
import { Input, InputField, InputIcon, InputSlot } from "@/components/ui/input";
import { Text } from "@/components/ui/text";
import { VStack } from "@/components/ui/vstack";
import { EyeIcon, EyeOffIcon } from "lucide-react-native";
import { useState } from "react";
import { Pressable } from "react-native";
interface ISignUp {
setCurrentComponent: React.Dispatch<React.SetStateAction<string>>;
}
const SignUp: React.FC<ISignUp> = ({ setCurrentComponent }) => {
const [showPassword, setShowPassword] = useState(false);
const handleState = () => {
setShowPassword((showState) => {
return !showState;
});
};
return (
<FormControl className="p-4 border rounded-lg border-outline-300">
<VStack space="xl">
<Heading className="text-typography-900 leading-2">Sign Up</Heading>
<VStack space="xs">
<Text className="text-typography-500 leading-1">Email</Text>
<Input>
<InputField type="text" />
</Input>
</VStack>
<VStack space="xs">
<Text className="text-typography-500 leading-1">Password</Text>
<Input className="text-center">
<InputField type={showPassword ? "text" : "password"} />
<InputSlot className="pr-3" onPress={handleState}>
{/* EyeIcon, EyeOffIcon are both imported from 'lucide-react-native' */}
<InputIcon
as={showPassword ? EyeIcon : EyeOffIcon}
className="text-blue-500"
/>
</InputSlot>
</Input>
<Pressable
className="mt-2"
onPress={() => setCurrentComponent("SignIn")}
>
<Text className="text-blue-500">Sign In</Text>
</Pressable>
</VStack>
<Button
className="bg-blue-500"
onPress={() => setCurrentComponent("SignIn")}
>
<ButtonText className="text-typography-0 text-center flex-1">
Sign Up
</ButtonText>
</Button>
</VStack>
</FormControl>
);
};
export default SignUp;
Create ForgotPassword.tsx
in your components
folder:
import { Pressable } from "react-native";
import { Box } from "./ui/box";
import { FormControl } from "./ui/form-control";
import { Heading } from "./ui/heading";
import { Input, InputField, InputSlot } from "./ui/input";
import { Text } from "./ui/text";
import { VStack } from "./ui/vstack";
import { Button, ButtonText } from "./ui/button";
interface IForgotPassword {
setCurrentComponent: React.Dispatch<React.SetStateAction<string>>;
}
const ForgotPassword: React.FC<IForgotPassword> = ({ setCurrentComponent }) => {
return (
<FormControl className="p-4 border rounded-lg border-outline-300">
<VStack space="xl">
<Heading className="text-typography-900 leading-2">
Forgot Password
</Heading>
<VStack space="xs">
<Text className="text-typography-500 leading-1">Email</Text>
<Input>
<InputField type="text" />
</Input>
<Pressable onPress={() => setCurrentComponent("SignIn")}>
<Text className="text-blue-500">Sign In</Text>
</Pressable>
</VStack>
<Button
className="bg-blue-500"
onPress={() => setCurrentComponent("SignIn")}
>
<ButtonText className="text-typography-0 text-center flex-1">
Send
</ButtonText>
</Button>
</VStack>
</FormControl>
);
};
export default ForgotPassword;
Install react native otp entry before we create the otp component.
yarn add react-native-otp-entry
Create OTP.tsx
in your components
folder:
import { OtpInput } from "react-native-otp-entry";
import { Box } from "./ui/box";
import { Button, ButtonText } from "./ui/button";
import { Heading } from "./ui/heading";
import { VStack } from "./ui/vstack";
import { Link } from "expo-router";
interface IOTP {
setCurrentComponent: React.Dispatch<React.SetStateAction<string>>;
}
const OTP: React.FC<IOTP> = ({ setCurrentComponent }) => {
return (
<Box className="border-outline-300 border rounded-lg">
<Box className="p-8">
<Heading>Enter the code we've sent your email address.</Heading>
<VStack className="mt-4" space="lg">
<OtpInput
numberOfDigits={6}
onTextChange={(text) => console.log(text)}
/>
<Link href="/" asChild>
<Button
className="bg-blue-500"
onPress={() => setCurrentComponent("SignIn")}
>
<ButtonText>Continue</ButtonText>
</Button>
</Link>
</VStack>
</Box>
</Box>
);
};
export default OTP;
That's it for this tutorial, we created user screen and added to our tab layout and created sign in, sign up, forgot password and otp components.
Next tutorial we'll create profile component.
0
0