DEV Community

Cover image for React Auth with LocalStorage: Simplified
Blessing Njoku
Blessing Njoku

Posted on

React Auth with LocalStorage: Simplified

Authentication is one of the most intimidating topics for beginners in React, especially when they hear terms like JWT, OAuth, and session cookies. But in this article, I'm going to break it down in a way that's practical, beginner-friendly, and focused on helping you understand how to store user data securely using just React and localStorage.

We’re going to build a simple app with login, logout, and a protected dashboard.

What You’ll Learn

  • How to set up a basic React app with routes
  • How to handle login and store user data in localStorage
  • How to protect a route (e.g., dashboard)
  • How to show login/logout conditionally

Step 1: Set Up Your React App

Use create-react-app or vite. For this example, I’ll use create-react-app:

npx create-react-app react-auth-localstorage
cd react-auth-localstorage
npm start

Step 2: Folder Structure

Let’s keep things clean:

src/
|-- components/
| |-- Home.js
| |-- Login.js
| |-- Dashboard.js
|-- App.js
|-- index.js

Step 3: Install React Router

-npm install react-router-dom

Now update App.js to add routing:

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './components/Home';
import Login from './components/Login';
import Dashboard from './components/Dashboard';

function App() {
  return (
    <Router>
      <Routes>
        <Route path='/' element={<Home />} />
        <Route path='/login' element={<Login />} />
        <Route path='/dashboard' element={<Dashboard />} />
      </Routes>
    </Router>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Step 4: Creating the Login Component

Let’s start simple. Our login form will accept email and password, and we’ll simulate login by storing a fake token in localStorage.

import { useNavigate } from 'react-router-dom';
import { useState } from 'react';

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const navigate = useNavigate();

  const handleLogin = (e) => {
    e.preventDefault();
    // Simulate login and save to localStorage
    if (email && password) {
      localStorage.setItem('user', JSON.stringify({ email }));
      navigate('/dashboard');
    } else {
      alert('Please fill in all fields');
    }
  };

  return (
    <form onSubmit={handleLogin}>
      <h2>Login</h2>
      <input type='email' placeholder='Email' value={email} onChange={e => setEmail(e.target.value)} /><br />
      <input type='password' placeholder='Password' value={password} onChange={e => setPassword(e.target.value)} /><br />
      <button type='submit'>Login</button>
    </form>
  );
};

export default Login;


Enter fullscreen mode Exit fullscreen mode

Step 5: Dashboard with Logout and Protection

import { useNavigate } from 'react-router-dom';
import { useEffect } from 'react';

const Dashboard = () => {
  const navigate = useNavigate();

  useEffect(() => {
    const user = JSON.parse(localStorage.getItem('user'));
    if (!user) {
      navigate('/login');
    }
  }, [navigate]);

  const handleLogout = () => {
    localStorage.removeItem('user');
    navigate('/login');
  };

  return (
    <div>
      <h2>Welcome to Dashboard</h2>
      <button onClick={handleLogout}>Logout</button>
    </div>
  );
};

export default Dashboard;

Enter fullscreen mode Exit fullscreen mode

Step 6: Home Component (Public Route)

const Home = () => {
  return (
    <div>
      <h1>Welcome to Our App</h1>
      <p>Click login to continue</p>
    </div>
  );
};

export default Home;

Enter fullscreen mode Exit fullscreen mode

Final Notes:

This is not production-grade authentication but is great for understanding state, routing, and localStorage.

Never store real tokens or passwords in localStorage in production apps.

Top comments (0)