Skip to content
Python Guides
Python Guides
  • Learn Python
    • Start Here
    • Python Roadmap
    • Python Tutorials
    • Python Libraries
  • Machine Learning
    • ML Tutorials Hub
    • NumPy
    • Pandas
    • Matplotlib
    • Scikit-Learn
    • Tensorflow
    • Keras
    • PyTorch
  • Web Development
  • Downloads
    • Python Projects
    • FREE eBook
    • FREE Training Course
  • Blogs

How to Build a React Login Component

Last Modified Date: December 12, 2025 by Bijay Kumar

As a React developer with over eight years of experience, I’ve built countless components, but the login form remains one of the most essential and frequently used. Whether you’re creating a corporate app for any company or a consumer-facing platform, a clean, functional login component is crucial.

In this article, I’ll walk you through building a React login component from scratch. I’ll share practical tips and best practices based on real-world projects I’ve worked on, so you can create a component that’s both user-friendly and easy to maintain.

Table of Contents:

Toggle
  • Build a Custom Login Component in React
  • Method 1: Simple React Login Component with State and Validation
    • Step 1: Set Up the Component
  • Method 2: Add Formik and Yup for Advanced Validation
    • Step 1: Install Dependencies
    • Step 2: Create the Login Component with Formik
  • Method 3: Handle Authentication with Context API
    • Step 1: Create an AuthContext
    • Step 2: Update Login Component to Use AuthContext
    • Step 3: Wrap Your App with AuthProvider

Build a Custom Login Component in React

Many developers rely on third-party libraries or external authentication services. While these are great, sometimes you need a lightweight, customizable login form tailored to your app’s unique requirements.

From my experience working with US clients, I’ve learned that a custom login component helps:

  • Maintain consistent branding and UI style
  • Control validation logic precisely
  • Integrate easily with backend APIs or services like Firebase or AWS Cognito

Method 1: Simple React Login Component with State and Validation

Let’s start with the basics, a simple login form that accepts email and password, validates input, and handles submission.

Step 1: Set Up the Component

Create a new file Login.js, and use React’s useState hook to manage form data and errors.

import React, { useState } from 'react';

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [errors, setErrors] = useState({});

  const validate = () => {
    const errors = {};
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    if (!email) {
      errors.email = 'Email is required';
    } else if (!emailRegex.test(email)) {
      errors.email = 'Email is invalid';
    }

    if (!password) {
      errors.password = 'Password is required';
    } else if (password.length < 6) {
      errors.password = 'Password must be at least 6 characters';
    }

    return errors;
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const validationErrors = validate();
    setErrors(validationErrors);

    if (Object.keys(validationErrors).length === 0) {
      // Normally, here you would call your API to login
      alert(`Logging in with Email: ${email}`);
      // Reset form (optional)
      setEmail('');
      setPassword('');
    }
  };

  return (
    <div style={{ maxWidth: '400px', margin: 'auto', padding: '2rem' }}>
      <h2>Login to Your Account</h2>
      <form onSubmit={handleSubmit} noValidate>
        <div style={{ marginBottom: '1rem' }}>
          <label htmlFor="email">Email:</label><br />
          <input
            type="email"
            id="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            style={{ width: '100%', padding: '0.5rem' }}
          />
          {errors.email && <p style={{ color: 'red' }}>{errors.email}</p>}
        </div>

        <div style={{ marginBottom: '1rem' }}>
          <label htmlFor="password">Password:</label><br />
          <input
            type="password"
            id="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            style={{ width: '100%', padding: '0.5rem' }}
          />
          {errors.password && <p style={{ color: 'red' }}>{errors.password}</p>}
        </div>

        <button type="submit" style={{ padding: '0.5rem 1rem' }}>
          Login
        </button>
      </form>
    </div>
  );
};

export default Login;

You can refer to the screenshot below to see the output.

Build a React Login Component
  • We use controlled inputs to keep track of the email and password.
  • The validate function checks for empty fields and validates the email format.
  • On submit, if there are no errors, we simulate a login action with an alert.
  • Error messages display below each input if validation fails.

Method 2: Add Formik and Yup for Advanced Validation

For more complex forms, I often use Formik with Yup to handle form state and validation elegantly. This approach reduces boilerplate and improves scalability.

Step 1: Install Dependencies

npm install formik yup

Step 2: Create the Login Component with Formik

Now let’s create the Login component using Formik and Yup to handle form state and validation efficiently.

import React from 'react';
import { useFormik } from 'formik';
import * as Yup from 'yup';

const Login = () => {
  const formik = useFormik({
    initialValues: {
      email: '',
      password: '',
    },
    validationSchema: Yup.object({
      email: Yup.string()
        .email('Invalid email address')
        .required('Required'),
      password: Yup.string()
        .min(6, 'Password must be at least 6 characters')
        .required('Required'),
    }),
    onSubmit: (values) => {
      alert(`Logging in with Email: ${values.email}`);
    },
  });

  return (
    <div style={{ maxWidth: '400px', margin: 'auto', padding: '2rem' }}>
      <h2>Login to Your Account</h2>
      <form onSubmit={formik.handleSubmit} noValidate>
        <div style={{ marginBottom: '1rem' }}>
          <label htmlFor="email">Email:</label><br />
          <input
            id="email"
            name="email"
            type="email"
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            value={formik.values.email}
            style={{ width: '100%', padding: '0.5rem' }}
          />
          {formik.touched.email && formik.errors.email ? (
            <p style={{ color: 'red' }}>{formik.errors.email}</p>
          ) : null}
        </div>

        <div style={{ marginBottom: '1rem' }}>
          <label htmlFor="password">Password:</label><br />
          <input
            id="password"
            name="password"
            type="password"
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            value={formik.values.password}
            style={{ width: '100%', padding: '0.5rem' }}
          />
          {formik.touched.password && formik.errors.password ? (
            <p style={{ color: 'red' }}>{formik.errors.password}</p>
          ) : null}
        </div>

        <button type="submit" style={{ padding: '0.5rem 1rem' }}>
          Login
        </button>
      </form>
    </div>
  );
};

export default Login;

You can refer to the screenshot below to see the output.

Build React Login Component
  • Formik manages form state and submission elegantly.
  • Yup provides declarative schema validation.
  • This combo reduces manual error handling and improves code readability.
  • It’s especially useful for larger forms or when you want to extend validation rules.

Method 3: Handle Authentication with Context API

In real applications, login is more than just a form. You need to manage authentication state globally.

Here’s a quick example of how you might integrate the login component with React’s Context API to manage user authentication.

Step 1: Create an AuthContext

Create an authentication context to store and manage the user’s login state globally.

import React, { createContext, useState, useContext } from 'react';

const AuthContext = createContext();

export const useAuth = () => useContext(AuthContext);

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  const login = (email, password) => {
    // Replace this with real API call
    if (email === 'user@example.com' && password === 'password123') {
      setUser({ email });
      return true;
    }
    return false;
  };

  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

Step 2: Update Login Component to Use AuthContext

Update the Login component to use the AuthContext for handling real login logic.

import React, { useState } from 'react';
import { useAuth } from './AuthContext';

const Login = () => {
  const { login } = useAuth();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    const success = login(email, password);
    if (!success) {
      setError('Invalid email or password');
    } else {
      setError('');
      alert('Login successful!');
    }
  };

  return (
    <div style={{ maxWidth: '400px', margin: 'auto', padding: '2rem' }}>
      <h2>Login to Your Account</h2>
      <form onSubmit={handleSubmit} noValidate>
        <div style={{ marginBottom: '1rem' }}>
          <label htmlFor="email">Email:</label><br />
          <input
            type="email"
            id="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            style={{ width: '100%', padding: '0.5rem' }}
          />
        </div>

        <div style={{ marginBottom: '1rem' }}>
          <label htmlFor="password">Password:</label><br />
          <input
            type="password"
            id="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            style={{ width: '100%', padding: '0.5rem' }}
          />
        </div>

        {error && <p style={{ color: 'red' }}>{error}</p>}

        <button type="submit" style={{ padding: '0.5rem 1rem' }}>
          Login
        </button>
      </form>
    </div>
  );
};

export default Login;

Step 3: Wrap Your App with AuthProvider

Wrap your entire app with AuthProvider so authentication works across all components.

import React from 'react';
import ReactDOM from 'react-dom';
import { AuthProvider } from './AuthContext';
import Login from './Login';

const App = () => (
  <AuthProvider>
    <Login />
  </AuthProvider>
);

ReactDOM.render(<App />, document.getElementById('root'));

You can see the output in the screenshot below.

How to Build a React Login Component

Building a React login component is a foundational skill for any React developer, especially when working on projects for US clients where user experience and security are paramount.

The first method I shared is perfect for beginners or quick prototypes. If you want more robust validation, Formik and Yup are your friends. And for real-world apps, integrating authentication state with React Context or other state management libraries is essential.

Remember, the login component is often the user’s first impression of your app. Keep it simple, clear, and responsive.

You may also like to read:

  • How to Import CSS Files in React Components
  • Optimize React Functional Components with React.memo
  • How to Fix React Component Not Defined Error
  • How to Pass Ref to Child Component in React
Bijay Kumar - Python and Machine Learning Expert
Bijay Kumar

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn

35 PyQt6 Python Interview Questions And Answers
Python Number Formatting: How to Add Commas to Large Numbers

Recent Posts

  • Recursion in Python: A Complete Guide with Examples
  • Regular Expressions in Python (re Module Guide)
  • Python dir() Function: A Practical Guide With Examples
  • Python dict() Function: A Practical Guide With Examples
  • Python delattr() Function: Remove Object Attributes
  • About Us
  • Contact
  • Privacy Policy
  • Sitemap
© 2026 PythonGuides.com

Free PDF · 112 pages

Get the 51 Python Programs PDF

Tell me where to send it and the free 112-page PDF is on its way.

No spam. You'll also get new Python tutorials by email. Unsubscribe anytime. Privacy policy

Check your inbox

Your free 51 Python Programs PDF is on its way to . Can't find it in a few minutes? Look in your Promotions or Spam folder.