Day 24 – Mini Blog Project in React (Part 2)
4 mins read

Day 24 – Mini Blog Project in React (Part 2)

In Part 1, we set up our Mini Blog Project with React, built routes, displayed blog posts, and added functionality to add, edit, and delete blogs.

👉 Now in Part 2, we’ll complete the project by adding:

  1. Authentication (Login/Logout flow)
  2. Protected Routes (only logged-in users can add, edit, or delete blogs)
  3. State Management Comparison — Context API, Redux Toolkit, and Zustand

By the end, you’ll have a fully functional mini blog app that showcases all the major React concepts we’ve learned.


Step 1: Add Authentication State

We’ll start with Context API to manage login/logout state.

👉 Create AuthContext.jsx:

import { createContext, useContext, useState } from "react";

const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  const login = () => setIsLoggedIn(true);
  const logout = () => setIsLoggedIn(false);

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

export function useAuth() {
  return useContext(AuthContext);
}

👉 Wrap the app in main.jsx:

import { AuthProvider } from "./AuthContext";

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <AuthProvider>
      <App />
    </AuthProvider>
  </React.StrictMode>
);

Step 2: Create Login Page

pages/Login.jsx:

import { useAuth } from "../AuthContext";
import { useNavigate } from "react-router-dom";

function Login() {
  const { login } = useAuth();
  const navigate = useNavigate();

  const handleLogin = (e) => {
    e.preventDefault();
    login(); // set logged in = true
    navigate("/");
  };

  return (
    <div className="max-w-md mx-auto p-6 bg-white shadow rounded">
      <h2 className="text-xl font-bold mb-4">Login</h2>
      <form onSubmit={handleLogin} className="space-y-4">
        <input
          type="text"
          placeholder="Username"
          className="w-full p-2 border rounded"
        />
        <input
          type="password"
          placeholder="Password"
          className="w-full p-2 border rounded"
        />
        <button
          type="submit"
          className="bg-indigo-600 text-white px-4 py-2 rounded"
        >
          Login
        </button>
      </form>
    </div>
  );
}

export default Login;

👉 Add route in App.jsx:

<Route path="/login" element={<Login />} />

Step 3: Protect Routes

We’ll restrict Add, Edit, and Delete blog pages to logged-in users.

👉 Create ProtectedRoute.jsx:

import { Navigate } from "react-router-dom";
import { useAuth } from "../AuthContext";

function ProtectedRoute({ children }) {
  const { isLoggedIn } = useAuth();

  if (!isLoggedIn) {
    return <Navigate to="/login" replace />;
  }

  return children;
}

export default ProtectedRoute;

👉 Use it in App.jsx:

import ProtectedRoute from "./components/ProtectedRoute";

<Route
  path="/add"
  element={
    <ProtectedRoute>
      <AddBlog blogs={blogs} setBlogs={setBlogs} />
    </ProtectedRoute>
  }
/>
<Route
  path="/edit/:id"
  element={
    <ProtectedRoute>
      <EditBlog blogs={blogs} setBlogs={setBlogs} />
    </ProtectedRoute>
  }
/>

👉 Now only logged-in users can add, edit, or delete blogs.


Step 4: Add Logout Button

In Header.jsx, update navigation:

import { useAuth } from "../AuthContext";

export default function Header() {
  const { isLoggedIn, logout } = useAuth();

  return (
    <header className="bg-white shadow">
      <div className="container mx-auto px-4 py-4 flex justify-between">
        <h1 className="font-bold text-lg">MiniBlog</h1>
        <nav className="flex gap-4">
          <a href="/">Home</a>
          {isLoggedIn ? (
            <>
              <a href="/add">Add Blog</a>
              <button onClick={logout} className="text-red-500">
                Logout
              </button>
            </>
          ) : (
            <a href="/login">Login</a>
          )}
        </nav>
      </div>
    </header>
  );
}

Step 5: State Management Comparison

So far, we’ve used Context API for authentication. But how would this look in Redux Toolkit and Zustand?

🔹 Context API (What we used here)

  • Simple setup.
  • Great for small apps.
  • But can get messy in larger apps.

🔹 Redux Toolkit Example

import { createSlice, configureStore } from "@reduxjs/toolkit";

const authSlice = createSlice({
  name: "auth",
  initialState: { isLoggedIn: false },
  reducers: {
    login: (state) => { state.isLoggedIn = true; },
    logout: (state) => { state.isLoggedIn = false; },
  },
});

export const { login, logout } = authSlice.actions;
export const store = configureStore({ reducer: { auth: authSlice.reducer } });

👉 Here we’d use useSelector + useDispatch in components.

🔹 Zustand Example

import { create } from "zustand";

const useAuthStore = create((set) => ({
  isLoggedIn: false,
  login: () => set({ isLoggedIn: true }),
  logout: () => set({ isLoggedIn: false }),
}));

export default useAuthStore;

👉 Just import the hook and use:

const { isLoggedIn, login, logout } = useAuthStore();

When to Choose What?

  • Context API → Small apps (like our Mini Blog).
  • Zustand → Medium apps, quick setup, minimal boilerplate.
  • Redux Toolkit → Large-scale apps with complex state.

Conclusion

In this blog, we completed our Mini Blog Project in React by adding:

  • Authentication (Login/Logout flow).
  • Protected Routes.
  • Compared state management solutions (Context, Redux Toolkit, Zustand).

👉 With this project, we’ve used almost every major concept of React:

Congratulations 🎉 — you’ve built a complete React project from scratch – Mini Blog Project in React!

After this you can start learning Node.js Tutorial Series for backend development.

Leave a Reply

Your email address will not be published. Required fields are marked *