DAY 10 : Deep Dive into React useEffect and Routing + Tip Calculator Project | My Web Dev Journey (ReactJS)


Introduction
Welcome to Day 10 of my web development journey!
For the past few days, I’ve been diving into ReactJS after completing the fundamentals of HTML, CSS, and JavaScript.
I build a tip calculator app to grasp the concept of useState
, event handling
, conditional rendering
.
I also learn new topics i.e. useEffect Hook, React Router, Dynamic routing.
I'm sharing my learning process in public to stay consistent and hopefully help others who are on a similar path.
Here’s what I learnt in last 3 days:
- Day 7:
→ Build a tip calculatorr app
→ make a clean UI
→ use useState() to track input values, result values and error
-> apply onClick() event on calcuate and reset button
-> shows error conditionally when input values is not valid
Day 8:
→ useEffect() Hook
→ Dependency Array
-> Cleanup FunctionDay 9:
→ React Router Library
→ Dynamic Routing
Let’s break down each of these topics below 👇
1. Tip Calculator App:
After getting comfortable with React fundamentals like useState
and handling forms, I created a Tip Calculator App to practice state management and dynamic UI updates based on user input.
This app helps the user:
- Enter the bill amount
- Enter tip percentage
- Enter number of people
- View the calculated tip & total amount per person, total bill
The main purpose of this project was to strengthen my understanding of controlled inputs, real-time calculations, and component-based design.
Project Features:
- Input field to enter bill amount.
- input field to enter tip percentage.
- Input for number of people splitting the bill.
- Real-time calculation of:
- Tip amount per person
- Total amount per person
- Total Bill amount
- Reset button to clear all inputs and results.
Concepts I Applied:
1. useState Hook
I used useState()
to manage all user inputs and outputs and errors:
// Input values
const [amount, setAmount] = useState("");
const [percentage, setPercentage] = useState(0);
const [people, setPeople] = useState(1);
// Error
const [error, setError] = useState("");
// Result values
const [tip, setTip] = useState(0);
const [perPerson, setPerPerson] = useState(0);
const [total, setTotal] = useState(0);
2. Handling Form Inputs
All inputs were controlled using React state. For example, when users enter a bill amount:
<input
type="number"
value={amount}
onChange={(e) => setAmount(Number(e.target.value))}
/>
3. Calculations & Dynamic Updates
Whenever user enter all the values in input field and click on calculate button, I calculate the total bill, tip and total per person and update on UI:
// calculate and set result to state variable
const tipAmount = (billAmount * tipPercentage) / 100 / numberOfpeople;
const totalAmount = billAmount + billAmount * (tipPercentage / 100);
const perPersonAmount = totalAmount / numberOfpeople;
setTip(Number(tipAmount.toFixed(2)));
setPerPerson(Number(perPersonAmount.toFixed(2)));
setTotal(Number(totalAmount.toFixed(2)));
4. Reset Functionality
A reset button clears all values and resets the calculations:
// Input values
setAmount("");
setPercentage(0);
setPeople(1);
// Error
setError("");
// Result values
setTip(0);
setPerPerson(0);
setTotal(0);
5. Error Handling
Conditionally rendering error on UI
:
- when input field is empty, showing error i.e "Enter valid values in all field".
- when user enter negative values in input field, showing error i.e "Values can't be negative".
if (
amount.trim() === "" ||
percentage.trim() === "" ||
people.trim() === ""
) {
setError("Enter valid values in all fields.");
clearInputs();
return;
}
const billAmount = Number(amount);
const tipPercentage = Number(percentage);
const numberOfpeople = Number(people);
if (billAmount < 0 || tipPercentage < 0 || numberOfpeople < 0) {
setError("values can't be negative");
clearInputs();
return;
}
2. useEffect() Hook:
The useEffect()
hook lets us perform side effects in functional components. It runs after every render by default and can be controlled with dependencies.
What are Side Effects?
A side effect is any operation that interacts with the outside world or has an effect outside the scope of the current function.
Common examples:
- Fetching data from an API
- Setting up subscriptions (e.g., event listeners)
- Working with timers (
setTimeout
,setInterval
) - Direct DOM manipulation
- Interacting with
localStorage
, cookies, etc.
Syntax:
useEffect(() => {
// code here (runs after render)
return () => {
// Cleanup code (optional)
};
}, [dependencies]);
- First argument: a callback with the side-effect logic.
- Second argument: an optional dependency array.
Dependency Array:
The second argument to useEffect is the Dependency Array.
It controls when the effect runs.
Case 1. Run only once (on Mount):
useEffect(() => {
console.log("Runs only once when component mounts");
}, []);
- If dependency array is empty means,
useEffect
only run once when component mounts.
Case 2. Run when dependencies change:
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Runs when count changes");
}, [count]);
const handleIncrement = () => {
setCount(count + 1);
};
return (
<div>
<h1>Count: {count}</h1>
<button onClick={handleIncrement}>Increment</button>
</div>
);
}
- Here, dependency array contain
count
state variable. - React monitor the
state
mention in dependency array, and whenever thestate
variable changes, It re-run the effect.
Case 3. Runs on every render:
useEffect(() => {
console.log("Runs after every render");
});
- If there is no dependency array, Whenever the component render,
Effect
will run.
Cleanup Function:
If effect sets up something like a timer, event listener, or subscription — clean it up to avoid memory leaks.
import { useState, useEffect } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
return () => clearInterval(interval); // Clear timer on unmount
}, []);
return <h2>Timer: {seconds}s</h2>;
}
Summary:
useEffect()
is used for side effects in React functional components.- It runs after the component renders.
- We can control when it runs using the dependency array.
- Always clean up effects when needed (like intervals or listeners).
3. React Router:
React Router is a standard library for handling routing in React applications.
It allows you to create multiple views or pages in a Single Page Application (SPA) — without reloading the entire browser page.
Why Do We Need React Router?
In a traditional multi-page website:
- Navigating to a new page causes a full-page reload.
In a React SPA, we want to:
- Navigate between views (e.g., Home, About, Contact)
- Avoid full-page reloads for better performance
- Maintain component state while switching pages
- Update the URL in the browser for navigation/history support
What React Router Enables:
React Router helps us by:
- Mapping URLs to components
- Rendering the correct component based on the current browser path
- Supporting nested routes, dynamic routes, and navigation guards
- Allowing linking, redirecting, and URL parameters
React Router V7:
React Router v7 introduces a data-first approach to routing, bringing powerful enhancements designed for both client-side and server-side rendering environments.
Key Features of React Router v7:
- File-Based Routing: Simplifies route management and mimics frameworks like Next.js.
- Data Loaders: Fetch data before rendering a route using
loader
functions. - Streaming Support: Enables streaming data and rendering partial pages while waiting.
- Enhanced Programmatic Routing: Create routes dynamically using
createBrowserRouter()
andRouterProvider
.
Core imports in V7:
import {
createBrowserRouter,
RouterProvider,
} from "react-router";
How to Use createBrowserRouter
and RouterProvider
:
1. Define Config Route:
Create an array of route objects (called RouteObject[]
):
// routes.js
import Home from "./pages/Home";
import About from "./pages/About";
import NotFound from "./pages/NotFound";
const routes = [
{
path: "/",
element: <Home />,
},
{
path: "/about",
element: <About />,
},
{
path: "*",
element: <NotFound />,
},
];
export default routes;
2. Create the Router:
In main.jsx
or index.js
:
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router";
import routes from "./routes";
const router = createBrowserRouter(routes);
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
Dynamic Routing:
In React Router v6 and v7, dynamic routing refers to defining routes that can handle changing parameters in the URL. These parameters can represent:
- User IDs
- Product slugs
- Blog post titles
- Any other path segment that is not hardcoded
Benefits of Dynamic Routing:
- Allows creating reusable components for multiple routes.
- Makes the application scalable and modular.
- Keeps URLs clean and semantic.
Steps:
- Define Dynamic Route:
// routes.js
import UserPage from "./pages/UserPage";
const routes = [
{
path: "/user/:id", // ":id" is dynamic
element: <UserPage />,
},
];
export default routes;
- Access Route Params in Component:
// UserPage.jsx
import { useParams } from "react-router";
function UserPage() {
const { id } = useParams(); // get dynamic param from URL
return (
<div>
<h2>User ID: {id}</h2>
</div>
);
}
export default UserPage;
- createBrowserRouter:
import { createBrowserRouter, RouterProvider } from "react-router";
import routes from "./routes";
const router = createBrowserRouter(routes);
<RouterProvider router={router} />;
4. What's next:
I’m continuing this journey and will be:
- Posting blogs every 3 days
- Also learning DSA using Java — check out my DSA Journey Blog
- You can follow my journey on Follow me on X (Twitter) where I post regular updates.
5. Conclusion:
In this part of my web development journey, I explored some powerful features of React that help build real-world, dynamic applications.
- I built a Tip Calculator App to apply core concepts like state management and user interactions.
- I learned about the
useEffect()
Hook and how to handle side effects like API calls and timers effectively. - I understood the importance of React Router for creating multi-page experiences in a Single Page Application (SPA).
- I also explored dynamic routing, which allows us to build flexible and scalable routes based on dynamic URL parameters.
Each topic helped me deepen my understanding of how React apps work behind the scenes and how to write cleaner, modular, and more interactive code.
🚀 With every project and concept, I feel more confident in building full-featured applications using React!
Stay tuned as I continue learning and building more exciting projects on my web development journey.
If you're on a similar journey, feel free to reach out or follow along — we’re all in this together.
Subscribe to my newsletter
Read articles from Ritik Kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Ritik Kumar
Ritik Kumar
👨💻 Aspiring Software Developer | MERN Stack Developer.🚀 Documenting my journey in Full-Stack Development & DSA with Java.📘 Focused on writing clean code, building real-world projects, and continuous learning.