
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:
- Authentication (Login/Logout flow)
- Protected Routes (only logged-in users can add, edit, or delete blogs)
- 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:
- Components & Props
- Hooks (
useState
,useEffect
,useRef
) - Forms & Controlled Inputs
- React Router
- CRUD operations
- Authentication
- State management
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.