Reactjs Projects

For Beginners To Experts


Reactjs Projects

Step-by-Step Guide to Running a React.js Project


  1. Install Node.js and npm:
    React requires Node.js and npm. Download and install from nodejs.org.

  2. Create a React project:
    Open your terminal/command prompt and run:
    npx create-react-app your-project-name
    This creates a new React project folder named your-project-name.

  3. Navigate to the project folder:
    Run:
    cd your-project-name

  4. Start the development server:
    Run:
    npm start
    This will launch the React app in your default browser at http://localhost:3000.

  5. Edit source files:
    Open src/App.js or any component file in your favorite code editor.
    Changes will auto-refresh in the browser.

  6. Install additional packages (optional):
    To add libraries like react-router, axios, or UI frameworks, run:
    npm install package-name

  7. Build for production:
    When ready to deploy, run:
    npm run build
    This creates an optimized build in the build folder.

  8. Deploy your app:
    Upload the contents of the build folder to your web server or hosting service.

Summary:

Running any React project involves installing Node.js, creating the app with create-react-app, navigating into the folder, and running npm start. You edit source files live, install needed packages, and build for deployment.

Common React Project Issues and How to Fix Them


  • “npm command not found” or “npx command not found”:
    - Ensure Node.js and npm are installed properly.
    - Run node -v and npm -v to verify installation.
    - If missing, reinstall Node.js from nodejs.org.

  • “Error: Cannot find module 'react-scripts'”:
    - Run npm install inside the project folder to install dependencies.
    - Delete node_modules folder and package-lock.json, then run npm install again.

  • “Port 3000 is already in use”:
    - Close other apps using port 3000 or run React on a different port:
    PORT=3001 npm start (on Mac/Linux)
    Or for Windows PowerShell:
    $env:PORT=3001; npm start

  • “Module parse failed” or syntax errors:
    - Check your code for typos, missing semicolons, or JSX errors.
    - Ensure you’re using correct import/export syntax.

  • “React Hook useEffect has missing dependencies” warning:
    - Add all variables used inside useEffect to the dependencies array.

  • “Failed to compile” after editing code:
    - Stop and restart the dev server.
    - Clear browser cache.

  • “npm start” freezes or crashes:
    - Delete node_modules and package-lock.json, then reinstall.
    - Update Node.js and npm to latest stable versions.

  • Issues with environment variables (.env files):
    - Environment variables must start with REACT_APP_ prefix.
    - Restart dev server after changing .env files.

  • Cannot find module after installing packages:
    - Double-check package name and spelling.
    - Run npm install again.

  • General tips:
    - Always read the full error message in the terminal and browser console.
    - Google the exact error message for specific solutions.
    - Use React DevTools extension for debugging.
    - Ensure you have stable internet while installing packages.
    - Keep your Node.js and npm updated.
    - If stuck, delete node_modules and reinstall dependencies.

Additional Common React Errors and How to Fix Them


  1. Error: “Failed to compile: Unexpected token”
    Cause: Usually due to JSX syntax errors like missing brackets, missing closing tags, or invalid JavaScript.
    How to fix:
    1. Check your JSX carefully for missing or extra < or > symbols.
    2. Make sure all JSX tags are properly closed (e.g., <div></div>).
    3. Ensure JavaScript expressions in JSX are wrapped in curly braces { }.
    4. Use a code editor with JSX linting (like VSCode with React extensions) for real-time error highlighting.

  2. Error: “Warning: Each child in a list should have a unique 'key' prop.”
    Cause: When rendering lists, React requires a unique key attribute on each item to optimize rendering.
    How to fix:
    1. Make sure your list items include a key prop with a unique value (like an ID or index).
    2. Example: <li key={item.id}>{item.name}</li>.
    3. Avoid using indexes as keys unless there’s no stable unique ID.

  3. Error: “React Hook useState is called in a loop” or “Invalid hook call”
    Cause: Hooks must be called only at the top level of React function components, not inside loops, conditions, or nested functions.
    How to fix:
    1. Move all hooks to the top level of your component function.
    2. Do not call hooks inside if statements, loops, or nested functions.
    3. Review your component to ensure hooks follow the rules of hooks (see React docs).

  4. Error: “Invariant failed: Objects are not valid as a React child”
    Cause: Trying to render an object directly inside JSX instead of a string or component.
    How to fix:
    1. Convert objects to strings before rendering (e.g., {JSON.stringify(object)}).
    2. Render only primitive values (string, number) or React components inside JSX.

  5. Error: “Cannot read property '...' of undefined”
    Cause: Accessing a property on an undefined or null object.
    How to fix:
    1. Check your data source for undefined or null values before accessing properties.
    2. Use optional chaining (e.g., user?.name) to safely access nested properties.
    3. Initialize your state variables properly to avoid undefined states.

  6. Error: “React component is not defined” or “Component is not exported/imported correctly”
    Cause: Components not imported or exported properly.
    How to fix:
    1. Ensure components are exported (default or named export) correctly.
    2. Import components with matching names and correct relative paths.
    3. Check for typos in import/export statements.

  7. Error: “Invalid prop type” or “Failed prop type” warnings
    Cause: Passing the wrong data type to a React component prop when using PropTypes.
    How to fix:
    1. Check your component’s PropTypes definitions.
    2. Pass props matching the expected types (string, number, bool, array, etc.).
    3. Use default props if some props are optional.

  8. Error: “Unhandled promise rejection” or “Fetch failed” when using API calls
    Cause: Network errors or incorrect fetch usage.
    How to fix:
    1. Check your API endpoint URLs and network connectivity.
    2. Use try-catch blocks or .catch() to handle fetch errors gracefully.
    3. Check browser console for detailed error messages.

  9. Error: “Cross-Origin Request Blocked (CORS policy)”
    Cause: Browser blocks requests to a different domain without proper CORS headers.
    How to fix:
    1. Use a proxy server during development (e.g., configure proxy in package.json).
    2. Ensure the API server allows your domain via CORS headers.
    3. For development, use browser extensions to bypass CORS (not recommended for production).

  10. Error: “Cannot use JSX outside of a React component”
    Cause: JSX syntax used in files or places where React is not properly set up.
    How to fix:
    1. Ensure your files have the .jsx or .js extension and Babel is configured to transpile JSX.
    2. Use Create React App or similar setups that include proper Babel config.
    3. Import React if using older React versions (<17) where it is required for JSX.

General Troubleshooting Tips:

  • Always restart your development server after fixing errors.
  • Clear browser cache or try incognito mode to avoid stale files.
  • Use online communities like Stack Overflow or React’s official docs for error-specific help.
  • Use debugging tools like React Developer Tools browser extension.
  • Keep dependencies updated but be careful of breaking changes.

How to Run:


  1. Create a React app using create-react-app

  2. npx create-react-app counter-app

  3. cd counter-app

  4. Replace App.js code with the following:

// Counter App - App.js
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0); // Initializes count state
return (
<div style={{ textAlign: 'center' }}>
<h1>Counter App</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
</div>
);
}
export default App;

Output:


Simple interface with buttons to increment or decrement a count.

How to Run:


  1. Create a React app using create-react-app

  2. npx create-react-app todo-app

  3. cd todo-app

  4. Replace App.js code with the following:

// Todo List - App.js
import React, { useState } from 'react';
function App() {
const [task, setTask] = useState(''); // For new task input
const [tasks, setTasks] = useState([]); // For storing tasks
const addTask = () => {
if (task !== '') {
setTasks([...tasks, task]);
setTask('');
}
};
return (
<div style={{ textAlign: 'center' }}>
<h1>Todo List</h1>
<input value={task} onChange={(e) => setTask(e.target.value)} />
<button onClick={addTask}>Add Task</button>
<ul>
{tasks.map((t, index) => (
<li key={index}>{t}</li>
))}
</ul>
</div>
);
}
export default App;

Output:


Allows user to input tasks and display them in a list.

How to Run:


  1. Create a React app using create-react-app

  2. npx create-react-app weather-app

  3. cd weather-app

  4. Install Axios: npm install axios

  5. Replace App.js code with the following:

// Weather App - App.js
import React, { useState } from 'react';
import axios from 'axios';
function App() {
const [city, setCity] = useState('');
const [weather, setWeather] = useState(null);
const fetchWeather = async () => {
const apiKey = 'your_api_key_here';
const response = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`);
setWeather(response.data);
};
return (
<div style={{ textAlign: 'center' }}>
<h1>Weather App</h1>
<input value={city} onChange={(e) => setCity(e.target.value)} />
<button onClick={fetchWeather}>Get Weather</button>
{weather && (
<div>
<p>Temperature: {weather.main.temp}°C</p>
<p>Weather: {weather.weather[0].description}</p>
</div>
)}
</div>
);
}
export default App;

Output:


Enter a city name to display the current weather.

How to Run:


  1. Create a React app using create-react-app

  2. npx create-react-app calculator-app

  3. cd calculator-app

  4. Replace App.js code with the following:

// Calculator App - App.js
import React, { useState } from 'react';
function App() {
const [input, setInput] = useState('');
const handleClick = (value) => setInput(input + value);
const handleClear = () => setInput('');
const handleEqual = () => setInput(eval(input).toString());
return (
<div style={{ textAlign: 'center' }}>
<h1>Calculator</h1>
<input value={input} readOnly />
<br />
{["1","2","3","+","4","5","6","-","7","8","9","*","0",".","=","/"].map(btn => (
<button onClick={() => btn === '=' ? handleEqual() : handleClick(btn)}>{btn}</button>
))}
<br />
<button onClick={handleClear}>Clear</button>
</div>
);
}
export default App;

Output:


Fully functional basic calculator with operators.

How to Run:


  1. Create a React app using create-react-app

  2. npx create-react-app form-validation

  3. cd form-validation

  4. Replace App.js code with the following:

// Form Validation - App.js
import React, { useState } from 'react';
function App() {
const [email, setEmail] = useState('');
const [error, setError] = useState('');
const validateEmail = () => {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!regex.test(email)) {
setError('Invalid email address');
} else {
setError('');
}
};
return (
<div style={{ textAlign: 'center' }}>
<h1>Form Validation</h1>
<input value={email} onChange={(e) => setEmail(e.target.value)} onBlur={validateEmail} />
<br />
<p style={{ color: 'red' }}>{error}</p>
</div>
);
}
export default App;

Output:


Simple email validation that displays an error message for invalid input.

How to Run:


  1. Create a React app using create-react-app

  2. npx create-react-app dark-mode-toggle

  3. cd dark-mode-toggle

  4. Replace App.js code with the following:

// Dark Mode Toggle - App.js
import React, { useState } from 'react';
function App() {
const [darkMode, setDarkMode] = useState(false);
const toggleMode = () => setDarkMode(!darkMode);
return (
<div style={{
textAlign: 'center',
backgroundColor: darkMode ? '#333' : '#fff',
color: darkMode ? '#fff' : '#000',
height: '100vh',
}}>
<h1>Dark Mode Toggle</h1>
<button onClick={toggleMode}>Toggle Mode</button>
</div>
);
}
export default App;

Output:


Switch between light and dark theme with a button click.

How to Run:


  1. Create a React app using create-react-app

  2. npx create-react-app age-calculator

  3. cd age-calculator

  4. Replace App.js code with the following:

// Age Calculator - App.js
import React, { useState } from 'react';
function App() {
const [dob, setDob] = useState('');
const [age, setAge] = useState(null);
const calculateAge = () => {
const birthDate = new Date(dob);
const diff = Date.now() - birthDate.getTime();
const ageDate = new Date(diff);
setAge(Math.abs(ageDate.getUTCFullYear() - 1970));
};
return (
<div style={{ textAlign: 'center' }}>
<h1>Age Calculator</h1>
<input type="date" onChange={(e) => setDob(e.target.value)} />
<button onClick={calculateAge}>Calculate Age</button>
{age !== null && <p>Your age is {age}</p>}
</div>
);
}
export default App;

Output:


Calculates user's age based on date of birth.

How to Run:


  1. Create a React app using create-react-app

  2. npx create-react-app quote-generator

  3. cd quote-generator

  4. Replace App.js code with the following:

// Random Quote Generator - App.js
import React, { useState } from 'react';
function App() {
const quotes = [
"Life is what happens when you're busy making other plans.",
"Get busy living or get busy dying.",
"You have within you right now, everything you need to deal with whatever the world can throw at you."
];
const [quote, setQuote] = useState('');
const generateQuote = () => {
const random = Math.floor(Math.random() * quotes.length);
setQuote(quotes[random]);
};
return (
<div style={{ textAlign: 'center' }}>
<h1>Random Quote Generator</h1>
<button onClick={generateQuote}>Generate Quote</button>
<p>{quote}</p>
</div>
);
}
export default App;

Output:


Displays a random quote from a predefined list.

How to Run:


  1. npx create-react-app bmi-calculator

  2. cd bmi-calculator

  3. Replace App.js code with the following:

// BMI Calculator - App.js
import React, { useState } from 'react'; // Import React and useState hook
function App() {
const [weight, setWeight] = useState(''); // State to store weight input
const [height, setHeight] = useState(''); // State to store height input
const [bmi, setBmi] = useState(null); // State to store calculated BMI
const calculateBMI = () => {
const heightInMeters = height / 100; // Convert height to meters
const calculatedBmi = weight / (heightInMeters * heightInMeters); // BMI formula
setBmi(calculatedBmi.toFixed(2)); // Set BMI result to 2 decimal places
};
return (
<div style={{ textAlign: 'center' }}>
<h1>BMI Calculator</h1>
<input type="number" placeholder="Weight (kg)" value={weight} onChange={(e) => setWeight(e.target.value)} />
<br/>
<input type="number" placeholder="Height (cm)" value={height} onChange={(e) => setHeight(e.target.value)} />
<br/>
<button onClick={calculateBMI}>Calculate BMI</button>
<br/>
{bmi && <p>Your BMI is: {bmi}</p>}
</div>
);
}
export default App;

Output:


Enter weight and height to get your BMI result.

How to Run:


  1. npx create-react-app password-generator

  2. cd password-generator

  3. Replace App.js code with the following:

// Password Generator - App.js
import React, { useState } from 'react'; // Import React and useState hook
function App() {
const [length, setLength] = useState(8); // State for password length
const [password, setPassword] = useState(''); // State for generated password
const generatePassword = () => {
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()'; // Character pool
let newPassword = ''; // Variable to store password
for (let i = 0; i < length; i++) { // Loop to generate password
newPassword += chars.charAt(Math.floor(Math.random() * chars.length));
}
setPassword(newPassword); // Set generated password
};
return (
<div style={{ textAlign: 'center' }}>
<h1>Password Generator</h1>
<input type="number" value={length} onChange={(e) => setLength(e.target.value)} />
<br/>
<button onClick={generatePassword}>Generate</button>
<br/>
<p>Generated Password: {password}</p>
</div>
);
}
export default App;

Output:


Generates a random password based on the selected length.

How to Run:


  1. npx create-react-app expense-tracker

  2. cd expense-tracker

  3. Replace App.js code with the following:

// Expense Tracker - App.js
import React, { useState } from 'react'; // Import React and useState hook
function App() {
const [transactions, setTransactions] = useState([]); // State to store transactions
const [desc, setDesc] = useState(''); // State for description input
const [amount, setAmount] = useState(''); // State for amount input
const addTransaction = () => {
if (!desc || !amount) return; // Prevent empty values
setTransactions([...transactions, { desc, amount: parseFloat(amount) }]); // Add new transaction
setDesc(''); // Clear description
setAmount(''); // Clear amount
};
const total = transactions.reduce((acc, curr) => acc + curr.amount, 0); // Calculate total
return (
<div style={{ textAlign: 'center' }}>
<h2>Expense Tracker</h2>
<input value={desc} onChange={(e) => setDesc(e.target.value)} placeholder="Description" />
<br/>
<input value={amount} onChange={(e) => setAmount(e.target.value)} placeholder="Amount" type="number" />
<br/>
<button onClick={addTransaction}>Add Transaction</button>
<br/>
<h3>Transactions</h3>
<ul>
{transactions.map((item, idx) => (
<li key={idx}>{item.desc} - ${item.amount}</li>
))}
</ul>
<h4>Total: ${total}</h4>
</div>
);
}
export default App;

Output:


Adds and displays transactions with a running total.

How to Run:


  1. npx create-react-app todo-list

  2. cd Recipe Finder

  3. Replace App.js with this code:

This Recipe Finder app lets users type an ingredient or dish name and fetches recipes from a public API. It uses React hooks (useState, useEffect) to manage state and side effects. When the user submits a search term, the app queries the Recipe Puppy API (a free recipe search API) and displays a list of recipes with titles and links. This project demonstrates how to handle input forms, fetch data asynchronously, and render lists dynamically in React.

//  Recipe Finder App.js
import React, { useState } from 'react';

function App() {
// State for the search input value
const [query, setQuery] = useState('');
// State to store the fetched recipes array
const [recipes, setRecipes] = useState([]);
// State to track loading status
const [loading, setLoading] = useState(false);
// State to store any error message
const [error, setError] = useState(null);

// Function to fetch recipes from the API
const fetchRecipes = async () => {
if (query.trim() === '') return; // Do nothing if query is empty
setLoading(true); // Set loading to true before fetch
setError(null); // Clear previous errors
try {
// Fetch data from Recipe Puppy API with query parameter
const response = await fetch(`https://cors-anywhere.herokuapp.com/http://www.recipepuppy.com/api/?q=${query}`);
const data = await response.json();
setRecipes(data.results); // Update recipes state with API results
} catch (err) {
setError('Failed to fetch recipes. Please try again.');
} finally {
setLoading(false); // Turn off loading state
}
};

// Handler for form submit event
const handleSubmit = (e) => {
e.preventDefault(); // Prevent default form reload behavior
fetchRecipes(); // Call fetch function
};

return (
<div style={{ maxWidth: 600, margin: '20px auto', padding: 20, fontFamily: 'Arial' }}>
<h2>Recipe Finder</h2>

<form onSubmit={handleSubmit} style={{ marginBottom: 20 }}>
<input
type="text"
placeholder="Enter ingredient or dish"
value={query}
onChange={e => setQuery(e.target.value)}
style={{ width: '80%', padding: 8, fontSize: 16 }}
/>
<button type="submit" style={{ padding: '8px 16px', fontSize: 16, marginLeft: 10 }}>Search</button>
</form>

{loading && <p>Loading recipes...</p>}
{error && <p style={{ color: 'red' }}>{error}</p>}

<ul style={{ paddingLeft: 0, listStyle: 'none' }}>
{recipes.map((recipe, index) => (
<li key={index} style={{ marginBottom: 15, borderBottom: '1px solid #ccc', paddingBottom: 10 }}>
<a href={recipe.href} target="_blank" rel="noreferrer" style={{ fontSize: 18, color: '#0066cc' }}>{recipe.title.trim()}</a>
<p>Ingredients: {recipe.ingredients}</p>
</li>
))}
</ul>
</div>
);
}

export default App;

Replace src/App.js

Open src/App.js and replace all content with the above Recipe Finder code.

CORS Proxy Note

The Recipe Puppy API doesn’t support CORS directly, so the code uses https://cors-anywhere.herokuapp.com/ as a proxy. You may need to enable the proxy temporarily:

  1. Visit https://cors-anywhere.herokuapp.com/corsdemo
  2. Click the "Request temporary access" button before running your app.

Start the App

Run this command:

npm start

This starts the development server and opens your app in the browser at http://localhost:3000.

Try It Out

Type an ingredient like "chicken" or "pasta" and click Search. Recipes will load below with clickable links.

//  Movie Search App - App.js
import React, { useState } from 'react';

function App() {
// State for storing search input value
const [query, setQuery] = useState('');
// State to store fetched movie results
const [movies, setMovies] = useState([]);
// State to manage loading status
const [loading, setLoading] = useState(false);
// State to handle error messages
const [error, setError] = useState(null);

// Function to fetch movies from OMDb API
const fetchMovies = async () => {
if (query.trim() === '') return; // Ignore empty search
setLoading(true); // Show loading message
setError(null); // Reset any previous error
try {
// Replace YOUR_API_KEY with your actual OMDb API key
const response = await fetch(`https://www.omdbapi.com/?s=${query}&apikey=YOUR_API_KEY`);
const data = await response.json();
if (data.Response === 'True') {
setMovies(data.Search); // Update movies state with search results
} else {
setError(data.Error || 'No movies found'); // Show API error message
setMovies([]); // Clear previous results
}
} catch (err) {
setError('Failed to fetch movies. Please try again.');
} finally {
setLoading(false); // Hide loading message
}
};

// Handle form submission
const handleSubmit = (e) => {
e.preventDefault(); // Prevent page reload
fetchMovies(); // Fetch movies for current query
};

return (
<div style={{ maxWidth: 700, margin: '20px auto', fontFamily: 'Arial', padding: 20 }}>
<h2>Movie Search App</h2>

<form onSubmit={handleSubmit} style={{ marginBottom: 20 }}>
<input
type="text"
placeholder="Search for movies..."
value={query}
onChange={e => setQuery(e.target.value)}
style={{ width: '75%', padding: 8, fontSize: 16 }}
/>
<button type="submit" style={{ padding: '8px 16px', fontSize: 16, marginLeft: 10 }}>Search</button>
</form>

{loading && <p>Loading movies...</p>}
{error && <p style={{ color: 'red' }}>{error}</p>}

<div style={{ display: 'flex', flexWrap: 'wrap', gap: 15 }}>
{movies.map(movie => (
<div key={movie.imdbID} style={{ border: '1px solid #ccc', padding: 10, width: 150 }}>
<img
src={movie.Poster !== 'N/A' ? movie.Poster : 'https://via.placeholder.com/150'}
alt={movie.Title}
style={{ width: '100%', height: 'auto' }}
/>
<h4 style={{ fontSize: 16, margin: '10px 0 5px' }}>{movie.Title}</h4>
<p style={{ margin: 0 }}>Year: {movie.Year}</p>
</div>
))}
</div>
</div>
);
}

export default App;

How to Run Movie Search App

Create React App

npx create-react-app movie-search-app  
cd movie-search-app

Get OMDb API Key

Visit OMDb API and request a free API key.

Replace YOUR_API_KEY in the code with your actual API key.

Replace src/App.js

Copy and paste the above code into src/App.js.

Start the App

npm start

Your app will open at http://localhost:3000.

Try Searching

Enter movie names (like "Batman", "Avengers") and hit Search to see results with posters and release years.

How to Run:


  1. npx create-react-app color-picker

  2. cd color-picker

  3. Replace App.js with this code:

// Color Picker - App.js
import React, { useState } from 'react';
function App() {
const [color, setColor] = useState('#000000');
return (
<div style={{textAlign:'center', padding:'20px'}}>
<h1>Color Picker</h1>
<input type="color" value={color} onChange={e => setColor(e.target.value)} />
<div style={{marginTop:'20px', width:'100px', height:'100px', backgroundColor: color, margin:'auto', border:'1px solid #000'}}></div>
<p>Selected Color: {color}</p>
</div>
);
}
export default App;

Output:


Pick a color using the color input and see a box update with the selected color.

//  Chat Application - App.js
import React, { useState, useEffect, useRef } from 'react';

function App() {
// State to hold the current message input by the user
const [message, setMessage] = useState('');
// State to hold all chat messages
const [messages, setMessages] = useState([]);
// Ref to the end of messages list for auto-scrolling
const messagesEndRef = useRef(null);

// Function to scroll chat to the bottom when messages update
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};

// useEffect to scroll to bottom whenever messages change
useEffect(() => {
scrollToBottom();
}, [messages]);

// Function to handle sending a new message
const sendMessage = () => {
if (message.trim() === '') return; // Ignore empty messages
const newMessage = { text: message, id: Date.now() }; // Create new message object
setMessages(prev => [...prev, newMessage]); // Append new message to messages array
setMessage(''); // Clear input box
};

// Handle Enter key press to send message
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
sendMessage();
}
};

return (
<div style={{ maxWidth: 600, margin: '20px auto', fontFamily: 'Arial', padding: 20, border: '1px solid #ccc', borderRadius: 5 }}>
<h2>Simple Chat Application</h2>

<div style={{ height: 300, overflowY: 'auto', border: '1px solid #ddd', padding: 10, marginBottom: 15 }}>
{messages.length === 0 && <p>No messages yet. Start chatting!</p>}
{messages.map(msg => (
<div key={msg.id} style={{ marginBottom: 10, padding: 8, backgroundColor: '#f1f1f1', borderRadius: 5 }}>
{msg.text}
</div>
))}
<div ref={messagesEndRef} /> {/* Dummy div for scroll to bottom */}
</div>

<input
type="text"
placeholder="Type your message..."
value={message}
onChange={e => setMessage(e.target.value)}
onKeyPress={handleKeyPress}
style={{ width: '80%', padding: 10, fontSize: 16 }}
/>
<button onClick={sendMessage} style={{ padding: '10px 20px', fontSize: 16, marginLeft: 10 }}>Send</button>
</div>
);
}

export default App;

How to Run Chat Application

Create React App

npx create-react-app chat-application  
cd chat-application

Replace src/App.js

Replace the entire content of src/App.js with the code above.

Start the App

npm start

The app will open at http://localhost:3000.

Use the App

  • Type messages into the input box and press Enter or click Send.
  • Messages will appear in the chat window above.
  • The chat scrolls automatically to show the newest message.

How to Run:


  1. npx create-react-app ecommerce-product-page

  2. cd ecommerce-product-page

  3. Replace src/App.js content with the following code

  4. Run npm start to launch the app

// E-commerce Product Page - App.js
import React, { useState } from 'react'; // Import React and useState hook

// Sample list of products
const PRODUCTS = [
{ id: 1, name: 'T-shirt', price: 19.99, category: 'Clothing' },
{ id: 2, name: 'Jeans', price: 49.99, category: 'Clothing' },
{ id: 3, name: 'Sneakers', price: 89.99, category: 'Footwear' },
{ id: 4, name: 'Hat', price: 14.99, category: 'Accessories' },
{ id: 5, name: 'Backpack', price: 39.99, category: 'Accessories' },
];

function App() {
const [products, setProducts] = useState(PRODUCTS); // Products to display
const [cart, setCart] = useState([]); // Cart items state
const [filterCategory, setFilterCategory] = useState('All'); // Current filter
const [sortOrder, setSortOrder] = useState('asc'); // Sort order state

// Filter products by category and sort them
const filterProducts = (category) => {
setFilterCategory(category);
let filtered = category === 'All' ? PRODUCTS : PRODUCTS.filter(p => p.category === category);
if (sortOrder === 'asc') {
filtered.sort((a, b) => a.price - b.price);
} else {
filtered.sort((a, b) => b.price - a.price);
}
setProducts(filtered);
};

// Change sorting order and update product list
const changeSortOrder = (order) => {
setSortOrder(order);
let sorted = [...products];
if (order === 'asc') {
sorted.sort((a, b) => a.price - b.price);
} else {
sorted.sort((a, b) => b.price - a.price);
}
setProducts(sorted);
};

// Add product to cart
const addToCart = (product) => {
setCart(prevCart => {
const existing = prevCart.find(item => item.id === product.id);
if (existing) {
// Increase quantity if already in cart
return prevCart.map(item => item.id === product.id ? {...item, quantity: item.quantity + 1} : item);
} else {
return [...prevCart, {...product, quantity: 1}];
}
});
};

return (
<div style={{ padding: '20px', maxWidth: '600px', margin: 'auto' }}>
<h1>E-commerce Product Page</h1>

<div>
<strong>Filter by Category:</strong><br/>
<button onClick={() => filterProducts('All')} disabled={filterCategory === 'All'}>All</button> 
<button onClick={() => filterProducts('Clothing')} disabled={filterCategory === 'Clothing'}>Clothing</button> 
<button onClick={() => filterProducts('Footwear')} disabled={filterCategory === 'Footwear'}>Footwear</button> 
<button onClick={() => filterProducts('Accessories')} disabled={filterCategory === 'Accessories'}>Accessories</button>
</div>

<div style={{ marginTop: '10px' }}>
<strong>Sort by Price:</strong><br/>
<button onClick={() => changeSortOrder('asc')} disabled={sortOrder === 'asc'}>Low to High</button> 
<button onClick={() => changeSortOrder('desc')} disabled={sortOrder === 'desc'}>High to Low</button>
</div>

<h3>Products</h3>
<ul style={{ listStyle: 'none', padding: 0 }}>
{products.map(product => (
<li key={product.id} style={{ marginBottom: '15px', border: '1px solid #ccc', padding: '10px' }}>
<div><strong>{product.name}</strong></div>
<div>Category: {product.category}</div>
<div>Price: ${product.price.toFixed(2)}</div>
<button onClick={() => addToCart(product)}>Add to Cart</button>
</li>
))}
</ul>

<h3>Shopping Cart</h3>
{cart.length === 0 ? (
<p>Your cart is empty.</p>
) : (
<ul style={{ listStyle: 'none', padding: 0 }}>
{cart.map(item => (
<li key={item.id} style={{ marginBottom: '10px' }}>
{item.name} - Quantity: {item.quantity} - Total: ${(item.price * item.quantity).toFixed(2)}
</li>
))}
</ul>
)}
</div>
);
}

export default App;

Output:


Displays products with category filters and sorting. Allows adding products to a shopping cart with quantity updates.

How to Run:


  1. npx create-react-app quiz-app

  2. cd quiz-app

  3. Replace App.js with this code:

// Quiz App - App.js
import React, { useState } from 'react';
const questions = [
{ question: 'What is 2 + 2?', options: ['3', '4', '5'], answer: '4' },
{ question: 'Capital of France?', options: ['London', 'Paris', 'Rome'], answer: 'Paris' },
];
function App() {
const [current, setCurrent] = useState(0);
const [score, setScore] = useState(0);
const [showScore, setShowScore] = useState(false);
const handleAnswer = (option) => {
if (option === questions[current].answer) setScore(score + 1);
if (current + 1 < questions.length) setCurrent(current + 1);
else setShowScore(true);
};
return (
<div style={{textAlign:'center', padding:'20px'}}>
<h1>Quiz App</h1>
{showScore ? (
<h2>Your score: {score} / {questions.length}</h2>
) : (
<div>
<p>{questions[current].question}</p>
{questions[current].options.map((opt, i) => (
<button key={i} onClick={() => handleAnswer(opt)}>{opt}</button>
))}
</div>
)}
</div>
);
}
export default App;

Output:


Simple quiz with score display at the end.

How to Run:


  1. npx create-react-app photo-gallery

  2. cd photo-gallery

  3. Replace App.js with the following code:

// Photo Gallery - App.js
import React, { useState } from 'react'; // Import React and useState
const photos = [ // Sample photo data
{ id: 1, category: 'Nature', url: 'https://via.placeholder.com/150?text=Nature+1' },
{ id: 2, category: 'City', url: 'https://via.placeholder.com/150?text=City+1' },
{ id: 3, category: 'Nature', url: 'https://via.placeholder.com/150?text=Nature+2' },
{ id: 4, category: 'City', url: 'https://via.placeholder.com/150?text=City+2' },
];
function App() {
const [filter, setFilter] = useState(''); // State to store category filter
const [search, setSearch] = useState(''); // State to store search keyword
const filteredPhotos = photos.filter(photo =>
(filter === '' || photo.category === filter) &&
photo.url.toLowerCase().includes(search.toLowerCase())
);
return (
<div style={{ padding: 20 }}>
<h1>Photo Gallery</h1>
<select onChange={(e) => setFilter(e.target.value)}>
<option value="">All</option>
<option value="Nature">Nature</option>
<option value="City">City</option>
</select>
<br/>
<input type="text" placeholder="Search..." onChange={(e) => setSearch(e.target.value)} />
<br/>
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
{filteredPhotos.map(photo => (
<img key={photo.id} src={photo.url} alt="photo" style={{ margin: 10 }} />
))}
</div>
</div>
);
}
export default App;

Output:


Displays photos with filters and search functionality.

Step-by-Step Instructions to Run the React Project

1. Install Node.js and npm

If you haven't already, install Node.js (which includes npm) from:
👉 https://nodejs.org

2. Create the React App Folder

Open your terminal (Command Prompt or Terminal app) and run:


npx create-react-app photo-gallery

  
This will create a new folder named photo-gallery with all the necessary files.

3. Navigate to Your Project Directory


cd photo-gallery

  

4. Open in Code Editor (Optional)

If you use VS Code:


code .

  

5. Replace App.js with Provided Code

- Open the src folder inside your project.
- Replace all contents of App.js with the code provided in the accordion (inside the <pre> tag).
- Make sure the HTML special characters like &lt; and &gt; are replaced back to < and > in the actual file.

6. Start the App

In the terminal:


npm start

  
This will launch your app in the browser at:
http://localhost:3000

7. Additional Configuration (If Needed)

If your project uses local file uploads or fetching from APIs, you may also need:


npm install <package-name>

  
Example: installing packages for drag-and-drop or Markdown parsing.

- Add CSS or image files manually inside the public/ or src/ directories as needed.


Your React project is now ready to run and customize!

How to Run:


  1. Open terminal and run: npx create-react-app markdown-editor

  2. Navigate to folder: cd markdown-editor

  3. Install the marked library to parse markdown: npm install marked

  4. Replace App.js with the code below:

// Markdown Editor - App.js
import React, { useState } from 'react'; // Import React and useState hook
import { marked } from 'marked'; // Import 'marked' to convert markdown to HTML
function App() {
const [markdown, setMarkdown] = useState('# Hello Markdown'); // State to store markdown text
const handleChange = (e) => {
setMarkdown(e.target.value); // Update markdown as user types
};
return (
<div style={{ display: 'flex', gap: '20px', padding: '20px' }}>
<textarea
style={{ width: '50%', height: '400px' }}
value={markdown}
onChange={handleChange}
/>
<div
style={{ width: '50%', height: '400px', border: '1px solid black', padding: '10px', overflowY: 'scroll' }}
dangerouslySetInnerHTML={{ __html: marked(markdown) }}
/>
</div>
);
}
export default App;

Output:


A real-time markdown editor where typing in the left textarea shows formatted preview on the right.

How to Run This React Markdown Editor

Step 1: Install Node.js

Download and install Node.js from:
https://nodejs.org
(This includes npm, the Node package manager.)

Step 2: Create a New React App

Open your terminal and run the following commands:


npx create-react-app markdown-editor
cd markdown-editor

  

Step 3: Install Markdown Parser (marked)

In the same terminal window, run:


npm install marked

  

Step 4: Edit the App

- Open the project in your code editor (e.g., Visual Studio Code).
- Go to src/App.js
- Replace everything in the file with the code provided (from the tutorial).
- If you're copying code from the browser, replace:
&lt; with < and &gt; with > in your code.

Step 5: Start the App

In the terminal, run:


npm start

  

This will launch your app in your default browser at:
http://localhost:3000


Your React Markdown Editor is now running and ready for use!

How to Run:


  1. npx create-react-app calendar-scheduler

  2. cd calendar-scheduler

  3. npm install react-big-calendar moment

  4. Replace App.js with:

// Calendar/Scheduler - App.js
import React from 'react';
import { Calendar, momentLocalizer } from 'react-big-calendar';
import moment from 'moment';
import 'react-big-calendar/lib/css/react-big-calendar.css';

const localizer = momentLocalizer(moment);

const events = [
  {
    title: 'Meeting',
    start: new Date(),
    end: new Date(moment().add(1, 'hour')),
  },
];

function App() {
  return (
    
); } export default App;

Output:


A functional calendar showing scheduled events using React Big Calendar.

How to Run:


  1. npx create-react-app music-player

  2. cd music-player

  3. Replace App.js with:

// Music Player - App.js
import React, { useRef, useState } from 'react';

function App() {
  const audioRef = useRef();
  const [isPlaying, setIsPlaying] = useState(false);

  const togglePlay = () => {
    if (isPlaying) {
      audioRef.current.pause();
    } else {
      audioRef.current.play();
    }
    setIsPlaying(!isPlaying);
  };

  return (
    

Music Player

); } export default App;

Output:


A basic music player that plays an MP3 file (replace "your-song.mp3" with a valid path).

How to Run:


  1. npx create-react-app task-board

  2. cd task-board

  3. npm install react-beautiful-dnd

  4. Replace App.js with:

         <!-- Music Player - App.js -->
import React, { useRef, useState } from 'react';

function App() {
const audioRef = useRef();
const [isPlaying, setIsPlaying] = useState(false);

const togglePlay = () => {
if (isPlaying) {
audioRef.current.pause();
} else {
audioRef.current.play();
}
setIsPlaying(!isPlaying);
};

return (
<div style={{ textAlign: 'center', padding: '50px' }}>
<h1>Music Player</h1>
<audio ref={audioRef} src="your-song.mp3" />
<br /><br />
<button onClick={togglePlay}>
{isPlaying ? 'Pause' : 'Play'}
</button>
</div>
);
}

export default App;

<h4>Output:</h4><br/>
A basic music player that plays an MP3 file (replace "your-song.mp3" with a valid path).

Output:


A simple Kanban-style task board where tasks can be reordered via drag-and-drop.

How to Run:


  1. Run npx create-react-app photo-gallery

  2. Navigate into the project folder: cd photo-gallery

  3. Replace src/App.js content with the code below

  4. Run npm start to start the development server

// Photo Gallery - App.js
import React, { useState } from 'react'; // Import React and useState hook

function App() {
// State to store images (url and category)
const [images, setImages] = useState([
{ id: 1, url: 'https://via.placeholder.com/150/0000FF', category: 'Nature' },
{ id: 2, url: 'https://via.placeholder.com/150/FF0000', category: 'People' },
{ id: 3, url: 'https://via.placeholder.com/150/00FF00', category: 'Architecture' },
]);
const [search, setSearch] = useState(''); // State for search input
const [category, setCategory] = useState('All'); // Selected category filter
const [newUrl, setNewUrl] = useState(''); // New image URL input
const [newCategory, setNewCategory] = useState('Nature'); // New image category selection

// Filter images based on search and category
const filteredImages = images.filter(img => {
return (category === 'All' || img.category === category) &&
img.url.toLowerCase().includes(search.toLowerCase());
});

// Add new image to state
const addImage = () => {
if (newUrl.trim() === '') return; // Ignore empty URL
const newImage = {
id: Date.now(),
url: newUrl.trim(),
category: newCategory
};
setImages([...images, newImage]);
setNewUrl(''); // Clear input
};

return (
<div style={{ maxWidth: '600px', margin: 'auto', textAlign: 'center' }}>
<h1>Photo Gallery</h1>

<input type="text" placeholder="Search by URL" value={search} onChange={(e) => setSearch(e.target.value)} />
<br/>
<select value={category} onChange={(e) => setCategory(e.target.value)}>
<option value="All">All</option>
<option value="Nature">Nature</option>
<option value="People">People</option>
<option value="Architecture">Architecture</option>
</select>
<br/>
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'center', gap: '10px', marginTop: '20px' }}>
{filteredImages.map(img => (
<img key={img.id} src={img.url} alt={img.category} style={{ width: '150px', height: '150px', objectFit: 'cover', borderRadius: '8px' }} />
))}
</div>

<h3>Add New Image</h3>
<input type="text" placeholder="Image URL" value={newUrl} onChange={(e) => setNewUrl(e.target.value)} />
<br/>
<select value={newCategory} onChange={(e) => setNewCategory(e.target.value)}>
<option value="Nature">Nature</option>
<option value="People">People</option>
<option value="Architecture">Architecture</option>
</select>
<br/>
<button onClick={addImage}>Add Image</button>
</div>
);
}

export default App;

Output:


Displays a photo gallery where users can search by URL, filter by category, and add new images with category selection.

Explanation: This app displays random quotes from a predefined list or API and allows users to share quotes via Twitter or other social platforms.

import React, { useState, useEffect } from 'react';

const quotes = [
"The only limit to our realization of tomorrow is our doubts of today.",
"Life is 10% what happens to us and 90% how we react to it.",
"Do what you can, with what you have, where you are.",
"Success is not final, failure is not fatal: It is the courage to continue that counts."
];

function RandomQuoteGenerator() {
const [quote, setQuote] = useState('');

useEffect(() => {
getRandomQuote();
}, []);

const getRandomQuote = () => {
const randomIndex = Math.floor(Math.random() * quotes.length);
setQuote(quotes[randomIndex]);
};

const shareQuote = () => {
const url = `https://twitter.com/intent/tweet?text=${encodeURIComponent(quote)}`;
window.open(url, '_blank');
};

return (
<div style={{padding: '20px', textAlign: 'center'}}>
<h2>Random Quote Generator</h2>
<p style={{fontStyle: 'italic', margin: '20px 0'}}>"{quote}"</p>
<button onClick={getRandomQuote}>New Quote</button>
<button onClick={shareQuote} style={{marginLeft: '10px'}}>Share on Twitter</button>
</div>
);
}

export default RandomQuoteGenerator;

Explanation: This app tests how fast and accurately the user can type a given sentence. It calculates words per minute and accuracy percentage by comparing user input to the target text.

import React, { useState, useEffect, useRef } from 'react';

const sampleText = "The quick brown fox jumps over the lazy dog.";

function TypingSpeedTest() {
const [input, setInput] = useState('');
const [startTime, setStartTime] = useState(null);
const [endTime, setEndTime] = useState(null);
const [finished, setFinished] = useState(false);
const inputRef = useRef(null);

useEffect(() => {
inputRef.current.focus();
}, []);

const handleChange = (e) => {
if (!startTime) setStartTime(Date.now());
const value = e.target.value;
setInput(value);
if (value === sampleText) {
setEndTime(Date.now());
setFinished(true);
}
};

const calculateWPM = () => {
const timeInMinutes = (endTime - startTime) / 60000;
const wordsTyped = sampleText.split(' ').length;
return Math.round(wordsTyped / timeInMinutes);
};

const calculateAccuracy = () => {
let correct = 0;
for (let i = 0; i < input.length; i++) {
if (input[i] === sampleText[i]) correct++;
}
return ((correct / sampleText.length) * 100).toFixed(2);
};

return (
<div style={{padding: '20px'}}>
<h2>Typing Speed Test</h2>
<p>Type the following text:</p>
<blockquote style={{background: '#f0f0f0', padding: '10px'}}>{sampleText}</blockquote>
<textarea
ref={inputRef}
value={input}
onChange={handleChange}
rows="4"
cols="50"
disabled={finished}
placeholder="Start typing here..."
/>
{finished && (
<div>
<p>Time: {(endTime - startTime) / 1000} seconds</p>
<p>WPM: {calculateWPM()}</p>
<p>Accuracy: {calculateAccuracy()}%</p>
</div>
)}
</div>
);
}

export default TypingSpeedTest;

Explanation: This app lets users search for YouTube videos using YouTube Data API and play selected videos embedded in the app.

import React, { useState } from 'react';

function YouTubeVideoPlayer() {
const [query, setQuery] = useState('');
const [videos, setVideos] = useState([]);
const [selectedVideo, setSelectedVideo] = useState(null);

const API_KEY = 'YOUR_YOUTUBE_API_KEY';

const searchVideos = async () => {
const response = await fetch(`
`https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&q=${query}&key=${API_KEY}`
);
const data = await response.json();
setVideos(data.items);
};

return (
<div style={{padding: '20px'}}>
<h2>YouTube Video Player</h2>
<input
type="text"
value={query}
onChange={e => setQuery(e.target.value)}
placeholder="Search videos..."
/>
<button onClick={searchVideos}>Search</button>
<div style={{marginTop: '20px'}}>
{videos.map(video => (
<div key={video.id.videoId} style={{marginBottom: '10px'}}>
<img
src={video.snippet.thumbnails.default.url}
alt={video.snippet.title}
style={{cursor: 'pointer'}}
onClick={() => setSelectedVideo(video)}
/>
<p>{video.snippet.title}</p>
</div>
))}
</div>
{selectedVideo && (
<div style={{marginTop: '20px'}}>
<h3>{selectedVideo.snippet.title}</h3>
<iframe
width="560"
height="315"
src={`https://www.youtube.com/embed/${selectedVideo.id.videoId}`}
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
title="YouTube video player"
/>
</div>
)}
</div>
);
}

export default YouTubeVideoPlayer;

Explanation: This app allows users to enter a location and fetches current weather data from a weather API, displaying temperature, conditions, and other relevant info.

import React, { useState } from 'react';

function WeatherApp() {
const [location, setLocation] = useState('');
const [weather, setWeather] = useState(null);
const API_KEY = 'YOUR_OPENWEATHERMAP_API_KEY';

const fetchWeather = async () => {
const response = await fetch(`
`https://api.openweathermap.org/data/2.5/weather?q=${location}&appid=${API_KEY}&units=metric`
);
const data = await response.json();
setWeather(data);
};

return (
<div style={{padding: '20px', maxWidth: '400px', margin: 'auto'}}>
<h2>Weather App</h2>
<input
type="text"
value={location}
onChange={e => setLocation(e.target.value)}
placeholder="Enter location"
/>
<button onClick={fetchWeather}>Get Weather</button>
{weather && weather.main && (
<div style={{marginTop: '20px'}}>
<p>Location: {weather.name}</p>
<p>Temperature: {weather.main.temp} °C</p>
<p>Condition: {weather.weather[0].description}</p>
</div>
)}
</div>
);
}

export default WeatherApp;

How to Run:


  1. Run npx create-react-app github-profile-viewer

  2. Navigate into the project folder: cd github-profile-viewer

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// GitHub Profile Viewer - App.js
import React, { useState } from 'react';
function App() {
const [username, setUsername] = useState(''); // GitHub username input
const [profile, setProfile] = useState(null); // User profile data
const [repos, setRepos] = useState([]); // User repositories
const [error, setError] = useState(null); // Error message

const fetchProfile = async () => {
setError(null);
setProfile(null);
setRepos([]);
if (!username) return;
try {
const resProfile = await fetch(`https://api.github.com/users/${username}`);
if (!resProfile.ok) throw new Error('User not found');
const dataProfile = await resProfile.json();
setProfile(dataProfile);

const resRepos = await fetch(`https://api.github.com/users/${username}/repos`);
const dataRepos = await resRepos.json();
setRepos(dataRepos);
} catch (err) {
setError(err.message);
}
};

return (
<div style={{ maxWidth: '600px', margin: 'auto', textAlign: 'center' }}>
<h1>GitHub Profile Viewer</h1>
<input type="text" placeholder="Enter GitHub username" value={username} onChange={e => setUsername(e.target.value)} />
<br/>
<button onClick={fetchProfile}>Search</button>
<br/>
{error && <p style={{ color: 'red' }}>{error}</p>}
{profile && (
<div>
<img src={profile.avatar_url} alt="avatar" style={{ width: '150px', borderRadius: '50%' }} />
<h2>{profile.name || profile.login}</h2>
<p>{profile.bio}</p>
<p>Followers: {profile.followers} | Following: {profile.following}</p>
<h3>Repositories</h3>
<ul style={{ listStyle: 'none', paddingLeft: 0, maxHeight: '200px', overflowY: 'auto' }}>
{repos.map(repo => (
<li key={repo.id}><a href={repo.html_url} target="_blank" rel="noopener noreferrer">{repo.name}</a></li>
))}
</ul>
</div>
)}
</div>
);
}

export default App;

Output:


Enter a GitHub username to fetch and display the user's profile and repository list.

How to Run:


  1. Run npx create-react-app infinite-scroll-list

  2. Navigate into the project folder: cd infinite-scroll-list

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Infinite Scroll List - App.js
import React, { useState, useEffect, useRef } from 'react';

function App() {
const [items, setItems] = useState([]); // List of items
const [page, setPage] = useState(1); // Current page
const loader = useRef(null); // Ref to loader div

// Simulate fetching items from API
const fetchItems = () => {
const newItems = Array.from({ length: 20 }, (_, i) => `Item ${(page - 1) * 20 + i + 1}`);
setItems(prev => [...prev, ...newItems]);
};

useEffect(() => {
fetchItems();
}, [page]);

useEffect(() => {
const options = { root: null, rootMargin: '20px', threshold: 1.0 };
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
setPage(prev => prev + 1);
}
}, options);
if (loader.current) observer.observe(loader.current);
return () => observer.disconnect();
}, []);

return (
<div style={{ maxWidth: '400px', margin: 'auto', padding: '20px' }}>
<h1>Infinite Scroll List</h1>
<ul style={{ listStyle: 'none', padding: 0 }}>
{items.map((item, index) => (
<li key={index} style={{ padding: '10px', borderBottom: '1px solid #ccc' }}>{item}</li>
))}
</ul>
<div ref={loader} style={{ height: '50px' }}>Loading more...</div>
</div>
);
}

export default App;

Output:


Displays a list that loads more items automatically as you scroll down.

How to Run:


  1. Run npx create-react-app currency-converter

  2. Navigate into the project folder: cd currency-converter

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Currency Converter - App.js
import React, { useState, useEffect } from 'react';

function App() {
const [rates, setRates] = useState({}); // Exchange rates
const [fromCurrency, setFromCurrency] = useState('USD'); // From currency
const [toCurrency, setToCurrency] = useState('EUR'); // To currency
const [amount, setAmount] = useState(1); // Amount to convert
const [result, setResult] = useState(null); // Converted result

useEffect(() => {
fetch('https://api.exchangerate-api.com/v4/latest/USD')
.then(res => res.json())
.then(data => setRates(data.rates));
}, []);

useEffect(() => {
if (!rates) return;
const rate = rates[toCurrency] / rates[fromCurrency];
setResult((amount * rate).toFixed(4));
}, [amount, fromCurrency, toCurrency, rates]);

return (
<div style={{ maxWidth: '400px', margin: 'auto', padding: '20px', textAlign: 'center' }}>
<h1>Currency Converter</h1>
<input type="number" value={amount} onChange={e => setAmount(e.target.value)} />
<br/>
<select value={fromCurrency} onChange={e => setFromCurrency(e.target.value)}>
{Object.keys(rates).map(cur => (
<option key={cur} value={cur}>{cur}</option>
))}
</select>
<span> → </span>
<select value={toCurrency} onChange={e => setToCurrency(e.target.value)}>
{Object.keys(rates).map(cur => (
<option key={cur} value={cur}>{cur}</option>
))}
</select>
<br/>
{result !== null && <p>{amount} {fromCurrency} = {result} {toCurrency}</p>}
</div>
);
}

export default App;

Output:


Convert an amount from one currency to another using live exchange rates.

How to Run:


  1. Run npx create-react-app stock-tracker

  2. Navigate into the project folder: cd stock-tracker

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

  5. Note: You need a free API key from a stock data provider like Alpha Vantage or Finnhub

// Real-time Stock Tracker - App.js
import React, { useState, useEffect } from 'react';
function App() {
const [symbol, setSymbol] = useState('AAPL'); // Default stock symbol
const [price, setPrice] = useState(null); // Current price
const [error, setError] = useState(null);

const API_KEY = 'YOUR_API_KEY_HERE'; // Replace with your real API key

useEffect(() => {
const fetchPrice = async () => {
try {
const response = await fetch(`
https://finnhub.io/api/v1/quote?symbol=${symbol}&token=${API_KEY}`);
const data = await response.json();
if (data.c) {
setPrice(data.c); // Current price
setError(null);
} else {
setError('Invalid symbol or API error');
setPrice(null);
}
} catch (err) {
setError('Failed to fetch data');
setPrice(null);
}
};
fetchPrice();
const interval = setInterval(fetchPrice, 10000); // Update every 10 seconds
return () => clearInterval(interval);
}, [symbol]);

return (
<div style={{ textAlign: 'center', maxWidth: '400px', margin: 'auto', padding: '20px' }}>
<h1>Real-time Stock Tracker</h1>
<input
type="text"
value={symbol}
onChange={e => setSymbol(e.target.value.toUpperCase())}
placeholder="Enter stock symbol, e.g. AAPL" />
<br/>
{error && <p style={{ color: 'red' }}>{error}</p>}
{price !== null && <p>Current price of {symbol}: $ {price}</p>}
</div>
);
}

export default App;

Output:


Shows live stock price updated every 10 seconds for the entered stock symbol.

How to Run:


  1. Run npx create-react-app job-board

  2. Navigate into the project folder: cd job-board

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Job Board - App.js
import React, { useState, useEffect } from 'react';
function App() {
const [jobs, setJobs] = useState([]);
const [search, setSearch] = useState('');
const [favorites, setFavorites] = useState([]);

useEffect(() => {
fetch('https://remotive.io/api/remote-jobs')
.then(res => res.json())
.then(data => setJobs(data.jobs))
.catch(() => setJobs([]));
}, []);

const toggleFavorite = (id) => {
setFavorites(prev =>
prev.includes(id) ? prev.filter(fav => fav !== id) : [...prev, id]
);
};

const filteredJobs = jobs.filter(job => job.title.toLowerCase().includes(search.toLowerCase()));

return (
<div style={{ maxWidth: '700px', margin: 'auto', padding: '20px' }}>
<h1>Job Board</h1>
<input
type="text"
placeholder="Search jobs"
value={search}
onChange={e => setSearch(e.target.value)}
style={{ width: '100%', padding: '10px', marginBottom: '20px' }} />

<h2>Jobs</h2>
{filteredJobs.length === 0 ? <p>No jobs found</p> : (
<ul style={{ listStyle: 'none', padding: 0 }}>
{filteredJobs.map(job => (
<li key={job.id} style={{ borderBottom: '1px solid #ccc', padding: '10px 0' }}>
<h3>{job.title}</h3>
<p>{job.company_name} - {job.candidate_required_location}</p>
<a href={job.url} target="_blank" rel="noopener noreferrer">View Details</a>
<br/>
<button onClick={() => toggleFavorite(job.id)}>{favorites.includes(job.id) ? 'Unsave' : 'Save'}</button>
</li>
))}
</ul>
)}
<h2>Favorites</h2>
{favorites.length === 0 ? <p>No favorites saved</p> : (
<ul>
{favorites.map(id => {
const job = jobs.find(j => j.id === id);
return job ? <li key={id}>{job.title} at {job.company_name}</li> : null;
})}
</ul>
)}
</div>
);
}

export default App;

Output:


Search remote jobs, view details, save favorites, and see your saved jobs list.

How to Run:


  1. Run npx create-react-app book-search

  2. Navigate into the project folder: cd book-search

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Book Search App - App.js
import React, { useState } from 'react';
function App() {
const [query, setQuery] = useState('');
const [books, setBooks] = useState([]);
const [error, setError] = useState(null);

const searchBooks = () => {
if (!query) return;
fetch(`https://www.googleapis.com/books/v1/volumes?q=${query}`)
.then(res => res.json())
.then(data => {
if (data.items) {
setBooks(data.items);
setError(null);
} else {
setBooks([]);
setError('No books found');
}
})
.catch(() => {
setBooks([]);
setError('Failed to fetch books');
});
};

return (
<div style={{ maxWidth: '600px', margin: 'auto', padding: '20px' }}>
<h1>Book Search</h1>
<input
type="text"
placeholder="Enter book title or author"
value={query}
onChange={e => setQuery(e.target.value)}
style={{ width: '100%', padding: '10px' }} />
<button onClick={searchBooks} style={{ marginTop: '10px' }}>Search</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
<ul>
{books.map(book => (
<li key={book.id} style={{ marginBottom: '15px' }}>
<strong>{book.volumeInfo.title}</strong> by {book.volumeInfo.authors ? book.volumeInfo.authors.join(', ') : 'Unknown'}
<br/>
<img src={book.volumeInfo.imageLinks ? book.volumeInfo.imageLinks.thumbnail : ''} alt="Book cover" />
<br/>
<a href={book.volumeInfo.infoLink} target="_blank" rel="noopener noreferrer">More Info</a>
</li>
))}
</ul>
</div>
);
}

export default App;

Output:


Search books by title or author using Google Books API, see covers and links to details.

How to Run:


  1. Run npx create-react-app fitness-tracker

  2. Navigate into the project folder: cd fitness-tracker

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Fitness Tracker - App.js
import React, { useState } from 'react';
function App() {
const [workouts, setWorkouts] = useState([]);
const [exercise, setExercise] = useState('');
const [duration, setDuration] = useState('');

const addWorkout = () => {
if (!exercise || !duration) return;
setWorkouts(prev => [...prev, { exercise, duration }]);
setExercise('');
setDuration('');
};

return (
<div style={{ maxWidth: '500px', margin: 'auto', padding: '20px' }}>
<h1>Fitness Tracker</h1>
<input
type="text"
placeholder="Exercise name"
value={exercise}
onChange={e => setExercise(e.target.value)}
style={{ width: '100%', marginBottom: '10px' }} />
<input
type="text"
placeholder="Duration (minutes)"
value={duration}
onChange={e => setDuration(e.target.value)}
style={{ width: '100%', marginBottom: '10px' }} />
<button onClick={addWorkout}>Add Workout</button>
<h2>Workout Log</h2>
<ul>
{workouts.map((w, i) => (
<li key={i}>{w.exercise} - {w.duration} minutes</li>
))}
</ul>
</div>
);
}

export default App;

Output:


Add and log exercises with duration, showing the workout log.

How to Run:


  1. Run npx create-react-app recipe-book

  2. Navigate into the project folder: cd recipe-book

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Recipe Book with Shopping List - App.js
import React, { useState } from 'react';
function App() {
const [recipes, setRecipes] = useState([]);
const [recipeName, setRecipeName] = useState('');
const [ingredient, setIngredient] = useState('');
const [currentIngredients, setCurrentIngredients] = useState([]);

const addIngredient = () => {
if (!ingredient) return;
setCurrentIngredients(prev => [...prev, ingredient]);
setIngredient('');
};

const addRecipe = () => {
if (!recipeName || currentIngredients.length === 0) return;
setRecipes(prev => [...prev, { name: recipeName, ingredients: currentIngredients }]);
setRecipeName('');
setCurrentIngredients([]);
};

const shoppingList = recipes.flatMap(r => r.ingredients);
const uniqueShoppingList = [...new Set(shoppingList)];

return (
<div style={{ maxWidth: '600px', margin: 'auto', padding: '20px' }}>
<h1>Recipe Book</h1>
<input
type="text"
placeholder="Recipe name"
value={recipeName}
onChange={e => setRecipeName(e.target.value)}
style={{ width: '100%', marginBottom: '10px' }} />
<input
type="text"
placeholder="Ingredient"
value={ingredient}
onChange={e => setIngredient(e.target.value)}
style={{ width: '100%', marginBottom: '10px' }} />
<button onClick={addIngredient} style={{ marginBottom: '10px' }}>Add Ingredient</button>
<button onClick={addRecipe}>Add Recipe</button>
<h2>Recipes</h2>
<ul>
{recipes.map((r, i) => (
<li key={i}><strong>{r.name}</strong>
<ul>
{r.ingredients.map((ing, idx) => (
<li key={idx}>{ing}</li>
))}
</ul>
</li>
))}
</ul>
<h2>Shopping List</h2>
<ul>
{uniqueShoppingList.map((item, idx) => (
<li key={idx}>{item}</li>
))}
</ul>
</div>
);
}

export default App;

Output:


Add recipes with ingredients, see all recipes listed, and a combined shopping list with unique ingredients.

How to Run:


  1. Run npx create-react-app note-taking-app

  2. Navigate into the project folder: cd note-taking-app

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Note-taking App - App.js
import React, { useState } from 'react';
function App() {
const [notes, setNotes] = useState([]);
const [title, setTitle] = useState('');
const [category, setCategory] = useState('General');
const [content, setContent] = useState('');

const addNote = () => {
if (!title || !content) return;
const newNote = { id: Date.now(), title, category, content };
setNotes(prev => [...prev, newNote]);
setTitle('');
setCategory('General');
setContent('');
};

const deleteNote = id => {
setNotes(prev => prev.filter(note => note.id !== id));
};

return (
<div style={{ maxWidth: '600px', margin: 'auto', padding: '20px' }}>
<h1>Note-taking App</h1>
<input
type="text"
placeholder="Title"
value={title}
onChange={e => setTitle(e.target.value)}
style={{ width: '100%', marginBottom: '10px', padding: '8px' }} />
<select
value={category}
onChange={e => setCategory(e.target.value)}
style={{ width: '100%', marginBottom: '10px', padding: '8px' }}>
<option value="General">General</option>
<option value="Work">Work</option>
<option value="Personal">Personal</option>
</select>
<textarea
placeholder="Content"
value={content}
onChange={e => setContent(e.target.value)}
style={{ width: '100%', height: '100px', marginBottom: '10px', padding: '8px' }} />
<button onClick={addNote} style={{ marginBottom: '20px' }}>Add Note</button>
<h2>Notes</h2>
<ul>
{notes.map(note => (
<li key={note.id} style={{ marginBottom: '15px', border: '1px solid #ccc', padding: '10px' }}>
<strong>{note.title}</strong> <em>({note.category})</em>
<p>{note.content}</p>
<button onClick={() => deleteNote(note.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}

export default App;

Output:


Create notes with title, category, and content; view and delete notes.

How to Run:


  1. Run npx create-react-app weather-dashboard

  2. Navigate into the project folder: cd weather-dashboard

  3. Replace src/App.js with the code below

  4. Obtain a free API key from OpenWeatherMap

  5. Replace YOUR_API_KEY in the code with your actual API key

  6. Run npm start to start the development server

// Weather Dashboard - App.js
import React, { useState } from 'react';
function App() {
const [city, setCity] = useState('');
const [weather, setWeather] = useState(null);
const [error, setError] = useState(null);

const fetchWeather = () => {
if (!city) return;
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY&units=metric`)
.then(res => res.json())
.then(data => {
if (data.cod === 200) {
setWeather(data);
setError(null);
} else {
setError(data.message);
setWeather(null);
}
})
.catch(() => {
setError('Failed to fetch weather');
setWeather(null);
});
};

return (
<div style={{ maxWidth: '500px', margin: 'auto', padding: '20px' }}>
<h1>Weather Dashboard</h1>
<input
type="text"
placeholder="Enter city"
value={city}
onChange={e => setCity(e.target.value)}
style={{ width: '100%', marginBottom: '10px', padding: '8px' }} />
<button onClick={fetchWeather} style={{ marginBottom: '20px' }}>Get Weather</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
{weather && (
<div>
<h2>{weather.name}, {weather.sys.country}</h2>
<p>Temperature: {weather.main.temp} °C</p>
<p>Weather: {weather.weather[0].description}</p>
<p>Humidity: {weather.main.humidity}%</p>
<p>Wind Speed: {weather.wind.speed} m/s</p>
</div>
)}
</div>
);
}

export default App;

Output:


Enter a city name to get current weather details including temperature, humidity, wind speed, and description.

How to Run:


  1. Run npx create-react-app countdown-timer

  2. Navigate into the project folder: cd countdown-timer

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Countdown Timer - App.js
import React, { useState, useEffect } from 'react';
function App() {
const [seconds, setSeconds] = useState(60);
const [isActive, setIsActive] = useState(false);

useEffect(() => {
let interval = null;
if (isActive && seconds > 0) {
interval = setInterval(() => {
setSeconds(seconds => seconds - 1);
}, 1000);
} else if (seconds === 0) {
setIsActive(false);
alert('Time is up!');
}
return () => clearInterval(interval);
}, [isActive, seconds]);

const toggle = () => {
setIsActive(!isActive);
};

const reset = () => {
setSeconds(60);
setIsActive(false);
};

return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>Countdown Timer</h1>
<div style={{ fontSize: '48px', margin: '20px' }}>{seconds} s</div>
<button onClick={toggle} style={{ marginRight: '10px' }}>{isActive ? 'Pause' : 'Start'}</button>
<button onClick={reset}>Reset</button>
</div>
);
}

export default App;

Output:


Start/pause a 60-second countdown timer with an alert when time is up.

How to Run:


  1. Run npx create-react-app pomodoro-timer

  2. Navigate into the project folder: cd pomodoro-timer

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Pomodoro Timer - App.js
import React, { useState, useEffect } from 'react';
function App() {
const [seconds, setSeconds] = useState(1500); // 25 minutes
const [isActive, setIsActive] = useState(false);
const [isWork, setIsWork] = useState(true);

useEffect(() => {
let interval = null;
if (isActive && seconds > 0) {
interval = setInterval(() => {
setSeconds(seconds => seconds - 1);
}, 1000);
} else if (seconds === 0) {
if (isWork) {
setSeconds(300); // 5 minutes break
setIsWork(false);
alert('Work session complete! Time for a break.');
} else {
setSeconds(1500); // 25 minutes work
setIsWork(true);
alert('Break over! Time to work.');
}
}
return () => clearInterval(interval);
}, [isActive, seconds, isWork]);

const toggle = () => {
setIsActive(!isActive);
};

const reset = () => {
setIsActive(false);
setSeconds(isWork ? 1500 : 300);
};

const formatTime = (sec) => {
const m = Math.floor(sec / 60);
const s = sec % 60;
return `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
};

return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>Pomodoro Timer</h1>
<h2>{isWork ? 'Work' : 'Break'} Session</h2>
<div style={{ fontSize: '48px', margin: '20px' }}>{formatTime(seconds)}</div>
<button onClick={toggle} style={{ marginRight: '10px' }}>{isActive ? 'Pause' : 'Start'}</button>
<button onClick={reset}>Reset</button>
</div>
);
}

export default App;

Output:


Timer switches between 25-minute work sessions and 5-minute breaks with alerts.

How to Run:


  1. Run npx create-react-app url-shortener

  2. Navigate into the project folder: cd url-shortener

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// URL Shortener - App.js
import React, { useState } from 'react';
function App() {
const [url, setUrl] = useState('');
const [shortUrl, setShortUrl] = useState('');
const [error, setError] = useState('');

const shortenUrl = () => {
if (!url) return;
// Using tinyurl API
fetch(`https://tinyurl.com/api-create.php?url=${encodeURIComponent(url)}`)
.then(res => res.text())
.then(data => {
setShortUrl(data);
setError('');
})
.catch(() => {
setError('Failed to shorten URL');
setShortUrl('');
});
};

return (
<div style={{ maxWidth: '500px', margin: 'auto', padding: '20px' }}>
<h1>URL Shortener</h1>
<input
type="text"
placeholder="Enter URL"
value={url}
onChange={e => setUrl(e.target.value)}
style={{ width: '100%', marginBottom: '10px', padding: '8px' }} />
<button onClick={shortenUrl} style={{ marginBottom: '20px' }}>Shorten</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
{shortUrl && (
<p>Short URL: <a href={shortUrl} target="_blank" rel="noopener noreferrer">{shortUrl}</a></p>
)}
</div>
);
}

export default App;

Output:


Enter a URL and get a shortened link using the TinyURL API.

How to Run:


  1. Run npx create-react-app expense-splitter

  2. Navigate into the project folder: cd expense-splitter

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Expense Splitter - App.js
import React, { useState } from 'react';
function App() {
const [friends, setFriends] = useState(['Alice', 'Bob', 'Charlie']);
const [amount, setAmount] = useState('');
const [paidBy, setPaidBy] = useState('Alice');
const [expenses, setExpenses] = useState([]);

const addExpense = () => {
const amt = parseFloat(amount);
if (!amt || !paidBy) return;
const newExpense = { id: Date.now(), amount: amt, paidBy };
setExpenses([...expenses, newExpense]);
setAmount('');
};

const total = expenses.reduce((acc, e) => acc + e.amount, 0);
const share = total / friends.length;

const balances = friends.map(friend => {
const paid = expenses
.filter(e => e.paidBy === friend)
.reduce((sum, e) => sum + e.amount, 0);
return { friend, balance: paid - share };
});

return (
<div style={{ maxWidth: '600px', margin: 'auto', padding: '20px' }}>
<h1>Expense Splitter</h1>
<input
type="number"
placeholder="Amount"
value={amount}
onChange={e => setAmount(e.target.value)}
style={{ marginRight: '10px', padding: '5px' }} />
<select value={paidBy} onChange={e => setPaidBy(e.target.value)} style={{ marginRight: '10px', padding: '5px' }}>
{friends.map(friend => (
<option key={friend} value={friend}>{friend}</option>
))}
</select>
<button onClick={addExpense}>Add Expense</button>

<h3>Expenses</h3>
<ul>
{expenses.map(e => (
<li key={e.id}>{e.paidBy} paid ${e.amount.toFixed(2)}</li>
))}
</ul>

<h3>Balances</h3>
<ul>
{balances.map(b => (
<li key={b.friend}>{b.friend}: {b.balance >= 0 ? 'Gets' : 'Owes'} ${Math.abs(b.balance).toFixed(2)}</li>
))}
</ul>
</div>
);
}

export default App;

Output:


Add expenses paid by friends and see how much each owes or gets back.

How to Run:


  1. Run npx create-react-app trivia-game

  2. Navigate into the project folder: cd trivia-game

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Trivia Game - App.js
import React, { useState, useEffect } from 'react';
function App() {
const [questions, setQuestions] = useState([]);
const [current, setCurrent] = useState(0);
const [score, setScore] = useState(0);
const [showScore, setShowScore] = useState(false);

useEffect(() => {
fetch('https://opentdb.com/api.php?amount=5&type=multiple')
.then(res => res.json())
.then(data => {
const formatted = data.results.map(q => {
const answers = [...q.incorrect_answers];
const randomIndex = Math.floor(Math.random() * (answers.length + 1));
answers.splice(randomIndex, 0, q.correct_answer);
return {
question: q.question,
answers,
correct: q.correct_answer
};
});
setQuestions(formatted);
});
}, []);

const handleAnswer = (answer) => {
if (answer === questions[current].correct) {
setScore(score + 1);
}
const next = current + 1;
if (next < questions.length) {
setCurrent(next);
} else {
setShowScore(true);
}
};

return (
<div style={{ maxWidth: '600px', margin: 'auto', padding: '20px' }}>
<h1>Trivia Game</h1>
{questions.length === 0 ? (
<p>Loading questions...</p>
) : showScore ? (
<div>
<h2>Your score: {score} / {questions.length}</h2>
<button onClick={() => { setCurrent(0); setScore(0); setShowScore(false); }}>Play Again</button>
</div>
) : (
<div>
<h3 dangerouslySetInnerHTML={{ __html: questions[current].question }} />
<ul style={{ listStyleType: 'none', padding: 0 }}>
{questions[current].answers.map((ans, i) => (
<li key={i}>
<button onClick={() => handleAnswer(ans)} style={{ margin: '5px', padding: '10px', width: '100%' }}>
<span dangerouslySetInnerHTML={{ __html: ans }} />
</button>
</li>
))}
</ul>
</div>
)}
</div>
);
}

export default App;

Output:


Play a 5-question multiple choice trivia game, with score tracking and replay.

How to Run:


  1. Run npx create-react-app weather-app

  2. Navigate into the project folder: cd weather-app

  3. Replace src/App.js with the code below

  4. Obtain a free API key from OpenWeatherMap

  5. Replace YOUR_API_KEY in the code with your API key

  6. Run npm start to start the development server

// Weather App - App.js
import React, { useState } from 'react';

function App() {
const [city, setCity] = useState('');
const [weather, setWeather] = useState(null);
const [error, setError] = useState('');

const fetchWeather = () => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY&units=metric`)
.then(res => {
if (!res.ok) {
throw new Error('City not found');
}
return res.json();
})
.then(data => {
setWeather(data);
setError('');
})
.catch(err => {
setError(err.message);
setWeather(null);
});
};

return (
<div style={{ maxWidth: '400px', margin: 'auto', padding: '20px' }}>
<h1>Weather App</h1>
<input
type="text"
placeholder="Enter city"
value={city}
onChange={e => setCity(e.target.value)}
style={{ padding: '8px', width: '100%', marginBottom: '10px' }} />
<button onClick={fetchWeather} style={{ padding: '8px 16px' }}>Get Weather</button>

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

{weather && (
<div style={{ marginTop: '20px' }}>
<h3>Weather in {weather.name}</h3>
<p>Temperature: {weather.main.temp}°C</p>
<p>Condition: {weather.weather[0].description}</p>
<p>Humidity: {weather.main.humidity}%</p>
<p>Wind Speed: {weather.wind.speed} m/s</p>
</div>
)}
</div>
);
}

export default App;

Output:


Enter a city name to get the current weather details like temperature, humidity, and wind speed.

How to Run:


  1. Run npx create-react-app todo-localstorage

  2. Navigate into the project folder: cd todo-localstorage

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// ToDo List with LocalStorage - App.js
import React, { useState, useEffect } from 'react';

function App() {
const [tasks, setTasks] = useState(() => {
// Retrieve tasks from localStorage or start with empty array
const saved = localStorage.getItem('tasks');
return saved ? JSON.parse(saved) : [];
});
const [input, setInput] = useState('');

useEffect(() => {
// Save tasks to localStorage whenever tasks change
localStorage.setItem('tasks', JSON.stringify(tasks));
}, [tasks]);

const addTask = () => {
if (input.trim() === '') return;
setTasks([...tasks, { id: Date.now(), text: input, completed: false }]);
setInput('');
};

const toggleTask = id => {
setTasks(tasks.map(task =>
task.id === id ? { ...task, completed: !task.completed } : task
));
};

const deleteTask = id => {
setTasks(tasks.filter(task => task.id !== id));
};

return (
<div style={{ maxWidth: '500px', margin: 'auto', padding: '20px' }}>
<h1>ToDo List</h1>
<input
type="text"
placeholder="Add new task"
value={input}
onChange={e => setInput(e.target.value)}
style={{ padding: '8px', width: '100%', marginBottom: '10px' }} />
<button onClick={addTask} style={{ padding: '8px 16px', marginBottom: '20px' }}>Add</button>

<ul style={{ listStyleType: 'none', padding: 0 }}>
{tasks.map(task => (
<li key={task.id} style={{ marginBottom: '10px' }}>
<input
type="checkbox"
checked={task.completed}
onChange={() => toggleTask(task.id)} />
<span style={{ textDecoration: task.completed ? 'line-through' : 'none', marginLeft: '8px' }}>{task.text}</span>
<button
onClick={() => deleteTask(task.id)}
style={{ marginLeft: '10px' }}>Delete</button>
</li>
))}
</ul>
</div>
);
}

export default App;

Output:


Add, complete, and delete tasks. Tasks persist between page reloads using LocalStorage.

How to Run:


  1. Run npx create-react-app calculator

  2. Navigate into the project folder: cd calculator

  3. Replace src/App.js with the code below

  4. Run npm start to start the development server

// Calculator - App.js
import React, { useState } from 'react';

function App() {
const [input, setInput] = useState('');

const appendInput = value => {
setInput(input + value);
};

const calculate = () => {
try {
setInput(String(eval(input)));
} catch {
setInput('Error');
}
};

const clear = () => {
setInput('');
};

return (
<div style={{ maxWidth: '320px', margin: 'auto', padding: '20px', textAlign: 'center' }}>
<h1>Calculator</h1>
<input
type="text"
value={input}
readOnly
style={{ width: '100%', padding: '10px', fontSize: '1.2rem', marginBottom: '10px' }} />

<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '10px' }}>
{['7','8','9','/','4','5','6','*','1','2','3','-','0','.','=','+'].map((btn, i) => (
<button
key={i}
onClick={() => {
if (btn === '=') calculate();
else appendInput(btn);
}}
style={{ padding: '15px', fontSize: '1.1rem' }}>
{btn}
</button>
))}
</div>

<button onClick={clear} style={{ marginTop: '10px', padding: '10px 20px' }}>Clear</button>
</div>
);
}

export default App;

Output:


A simple calculator supporting basic arithmetic operations with a clear button.

How to Run:


  1. Run npx create-react-app movie-search

  2. Navigate into the project folder: cd movie-search

  3. Replace src/App.js with the code below

  4. Obtain a free API key from OMDb API

  5. Replace YOUR_API_KEY in the code below with your API key

  6. Run npm start to launch the app

// Movie Search App - App.js
import React, { useState } from 'react';

function App() {
const [query, setQuery] = useState('');
const [movies, setMovies] = useState([]);
const [error, setError] = useState('');

const searchMovies = () => {
fetch(`https://www.omdbapi.com/?apikey=YOUR_API_KEY&s=${query}`)
.then(res => res.json())
.then(data => {
if (data.Response === 'True') {
setMovies(data.Search);
setError('');
} else {
setMovies([]);
setError(data.Error);
}
})
.catch(() => {
setError('Failed to fetch movies');
setMovies([]);
});
};

return (
<div style={{ maxWidth: '600px', margin: 'auto', padding: '20px' }}>
<h1>Movie Search</h1>
<input
type="text"
placeholder="Search movies..."
value={query}
onChange={e => setQuery(e.target.value)}
style={{ padding: '8px', width: '100%', marginBottom: '10px' }} />
<button onClick={searchMovies} style={{ padding: '8px 16px' }}>Search</button>

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

<ul style={{ listStyleType: 'none', padding: 0 }}>
{movies.map(movie => (
<li key={movie.imdbID} style={{ marginBottom: '20px', borderBottom: '1px solid #ccc', paddingBottom: '10px' }}>
<img src={movie.Poster !== 'N/A' ? movie.Poster : 'https://via.placeholder.com/100x150'} alt={movie.Title} style={{ width: '100px', marginRight: '10px' }} />
<strong>{movie.Title}</strong> ({movie.Year})
</li>
))}
</ul>
</div>
);
}

export default App;

Output:


Search for movies by title. Displays posters, titles, and release years. Shows error messages if no results.

How to Run:


  1. Run: npx create-react-app portfolio-website

  2. Navigate: cd portfolio-website

  3. Replace App.js with the code below:

          <!-- Portfolio Website - App.js -->
import React from 'react';

function App() {
return (
<div style={{ fontFamily: 'Arial, sans-serif', padding: '20px' }}>
<header style={{ textAlign: 'center', marginBottom: '40px' }}>
<h1>My Portfolio</h1>
<p>Welcome to my personal portfolio website!</p>
</header>

<section style={{ marginBottom: '30px' }}>
<h2>About Me</h2>
<p>Hello! I'm a passionate developer specializing in building user-friendly web applications using React.</p>
</section>

<section style={{ marginBottom: '30px' }}>
<h2>Skills</h2>
<ul>
<li>JavaScript</li>
<li>React</li>
<li>HTML & CSS</li>
<li>Node.js</li>
</ul>
</section>

<section>
<h2>Contact</h2>
<p>Email: example@domain.com</p>
<p>LinkedIn: <a href="https://linkedin.com" target="_blank" rel="noreferrer">linkedin.com</a></p>
</section>
</div>
);
}

export default App;

<h4>Output:</h4><br/>
A simple portfolio website with sections for About, Skills, and Contact using React.

Output:


A simple portfolio website with sections for About, Skills, and Contact using React.

How to Run:


  1. Run: npx create-react-app blog-platform

  2. Navigate: cd blog-platform

  3. Install Markdown Support: npm install react-markdown

  4. Replace App.js with the code below:

// Blog Platform - App.js
import React, { useState } from 'react';
import ReactMarkdown from 'react-markdown';

function App() {
  const [posts, setPosts] = useState([]); // State to hold all blog posts
  const [content, setContent] = useState(''); // Markdown content of new post

  const addPost = () => {
    if (content.trim()) {
      setPosts([...posts, content]); // Add the new post to the list
      setContent(''); // Clear the input
    }
  };

  const deletePost = (index) => {
    const updatedPosts = posts.filter((_, i) => i !== index); // Remove the selected post
    setPosts(updatedPosts); // Update state
  };

  return (
    <div style={{ padding: '20px', fontFamily: 'Arial' }}>
      <h1>Markdown Blog</h1>
      <textarea
        value={content}
        onChange={(e) => setContent(e.target.value)}
        placeholder="Write your markdown here..."
        rows="6"
        cols="60"
      /><br/>
      <button onClick={addPost}>Add Post</button>

      <hr/>
      <h2>Posts</h2>
      {posts.map((post, index) => (
        <div key={index} style={{ border: '1px solid #ccc', margin: '10px 0', padding: '10px' }}>
          <ReactMarkdown>{post}</ReactMarkdown>
          <button onClick={() => deletePost(index)}>Delete</button>
        </div>
      ))}
    </div>
  );
}

export default App;

Output:


A simple blog platform where users can write markdown content, see a live preview, and manage posts by adding or deleting them.

How to Run:


  1. Run: npx create-react-app expense-dashboard

  2. Navigate: cd expense-dashboard

  3. Install Chart Library: npm install recharts

  4. Replace App.js with the code below:

// Expense Dashboard - App.js
import React, { useState } from 'react';
import { BarChart, Bar, XAxis, YAxis, Tooltip, CartesianGrid } from 'recharts';

function App() {
  const [expenses, setExpenses] = useState([]);
  const [item, setItem] = useState('');
  const [amount, setAmount] = useState('');

  const addExpense = () => {
    if (item && amount) {
      setExpenses([...expenses, { name: item, amount: parseFloat(amount) }]);
      setItem('');
      setAmount('');
    }
  };

  return (
    <div style={{ padding: 20, fontFamily: 'Arial' }}>
      <h1>Expense Dashboard</h1>
      <input placeholder="Item" value={item} onChange={(e) => setItem(e.target.value)} /> 
      <input placeholder="Amount" value={amount} onChange={(e) => setAmount(e.target.value)} /> 
      <button onClick={addExpense}>Add</button>

      <BarChart width={500} height={300} data={expenses}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="name" />
        <YAxis />
        <Tooltip />
        <Bar dataKey="amount" fill="#8884d8" />
      </BarChart>
    </div>
  );
}

export default App;

Output:


An expense dashboard where users can input expense name and amount and view a bar chart showing the expense breakdown.

How to Run:


  1. Run: npx create-react-app note-app

  2. Navigate: cd note-app

  3. Replace App.js with the code below:

// Note-taking App - App.js
import React, { useState } from 'react';

function App() {
  const [notes, setNotes] = useState([]); // Array of notes
  const [text, setText] = useState('');   // Input for new note

  const addNote = () => {
    if (text.trim()) {
      setNotes([...notes, text]);
      setText('');
    }
  };

  const deleteNote = (index) => {
    const updatedNotes = notes.filter((_, i) => i !== index);
    setNotes(updatedNotes);
  };

  return (
    <div style={{ padding: '20px', fontFamily: 'Arial' }}>
      <h1>Note-taking App</h1>
      <input
        type="text"
        placeholder="Write a note..."
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
      <button onClick={addNote}>Add Note</button>

      <ul>
        {notes.map((note, index) => (
          <li key={index}>
            {note}
            <button onClick={() => deleteNote(index)} style={{ marginLeft: '10px' }}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

Output:


A basic React note-taking app where users can write, view, and delete notes. Notes are displayed in a list and can be removed individually.

How to Run:


  1. Run: npx create-react-app chatbot-interface

  2. Navigate: cd chatbot-interface

  3. Replace App.js with the code below:

  4. Run the app: npm start

// Chatbot Interface - App.js
import React, { useState } from 'react';

function App() {
  // State to hold messages as an array of objects {sender: 'user'|'bot', text: string}
  const [messages, setMessages] = useState([
    { sender: 'bot', text: 'Hello! How can I assist you today?' }
  ]);
  // State to hold current user input
  const [input, setInput] = useState('');

  // Function to simulate bot reply based on user message
  const getBotReply = (message) => {
    const msg = message.toLowerCase();
    if (msg.includes('hello') || msg.includes('hi')) {
      return 'Hi there! What can I do for you?';
    } else if (msg.includes('help')) {
      return 'Sure, I am here to help. Please ask your question.';
    } else if (msg.includes('bye')) {
      return 'Goodbye! Have a great day!';
    }
    return "I'm not sure how to respond to that.";
  };

  // Handle sending message
  const sendMessage = () => {
    if (!input.trim()) return; // Ignore empty input
    const userMessage = { sender: 'user', text: input };
    // Add user message
    setMessages(prev => [...prev, userMessage]);
    // Generate bot reply
    const botReply = { sender: 'bot', text: getBotReply(input) };
    // Add bot reply after a short delay to simulate typing
    setTimeout(() => setMessages(prev => [...prev, botReply]), 500);
    setInput(''); // Clear input field
  };

  // Handle enter key press in input
  const handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      sendMessage();
    }
  };

  return (
    <div style={{ maxWidth: '500px', margin: 'auto', fontFamily: 'Arial', padding: '20px', border: '1px solid #ccc', borderRadius: '8px' }}>
      <h1>Simple Chatbot Interface</h1>
      <div style={{ height: '300px', overflowY: 'auto', border: '1px solid #ddd', padding: '10px', marginBottom: '10px' }}>
        {messages.map((msg, index) => (
          <div key={index} style={{ textAlign: msg.sender === 'user' ? 'right' : 'left', margin: '5px 0' }}>
            <span style={{ display: 'inline-block', padding: '8px 12px', borderRadius: '15px', backgroundColor: msg.sender === 'user' ? '#0d6efd' : '#e4e6eb', color: msg.sender === 'user' ? 'white' : 'black' }}>
              {msg.text}
            </span>
          </div>
        ))}
      </div>
      <input
        type="text"
        placeholder="Type your message..."
        value={input}
        onChange={(e) => setInput(e.target.value)}
        onKeyPress={handleKeyPress}
        style={{ width: '80%', padding: '10px', borderRadius: '4px', border: '1px solid #ccc' }}
      />
      <button onClick={sendMessage} style={{ padding: '10px 15px', marginLeft: '5px', borderRadius: '4px', border: 'none', backgroundColor: '#0d6efd', color: 'white' }}>Send</button>
    </div>
  );
}

export default App;
      

Output:


A simple chatbot interface that responds to basic greetings and queries with preset answers, allowing the user to type messages and see responses.

How to Run:


  1. Run: npx create-react-app file-upload-app

  2. Navigate: cd file-upload-app

  3. Replace App.js with the code below:

  4. Run the app: npm start

// File Upload App - App.js
import React, { useState } from 'react';

function App() {
  const [files, setFiles] = useState([]);
  const [uploadProgress, setUploadProgress] = useState({}); // track progress by file name

  // Handle file input change
  const handleFileChange = (e) => {
    const selectedFiles = Array.from(e.target.files);
    // Add new files to state with preview URLs
    const filesWithPreview = selectedFiles.map(file => ({
      file,
      preview: URL.createObjectURL(file)
    }));
    setFiles(prev => [...prev, ...filesWithPreview]);
  };

  // Simulate file upload progress
  const uploadFiles = () => {
    files.forEach(({ file }) => {
      const interval = setInterval(() => {
        setUploadProgress(prev => {
          const currentProgress = prev[file.name] || 0;
          if (currentProgress >= 100) {
            clearInterval(interval);
            return prev;
          }
          return { ...prev, [file.name]: currentProgress + 10 };
        });
      }, 300);
    });
  };

  return (
    <div style={{ maxWidth: '600px', margin: 'auto', fontFamily: 'Arial', padding: '20px' }}>
      <h1>File Upload App</h1>
      <input type="file" multiple onChange={handleFileChange} /><br/><br/>
      <button onClick={uploadFiles} disabled={files.length === 0}>Upload Files</button>

      <div style={{ marginTop: '20px' }}>
        {files.map(({ file, preview }) => (
          <div key={file.name} style={{ marginBottom: '15px' }}>
            <strong>{file.name}</strong><br/>
            <img src={preview} alt={file.name} style={{ width: '100px', height: '100px', objectFit: 'cover', display: 'block', marginBottom: '5px' }} />
            <div style={{ width: '100%', backgroundColor: '#eee', borderRadius: '4px' }}>
              <div
                style={{
                  width: `${uploadProgress[file.name] || 0}%`,
                  height: '10px',
                  backgroundColor: '#0d6efd',
                  borderRadius: '4px',
                  transition: 'width 0.3s ease'
                }}
              />
            </div>
            <span>{uploadProgress[file.name] ? `${uploadProgress[file.name]}%` : 'Not uploaded'}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;
      

Output:


Users can select multiple files to upload. Each file shows a preview image, and a progress bar simulates upload progress in increments.

How to Run:


  1. Run: npx create-react-app image-carousel

  2. Navigate: cd image-carousel

  3. Replace App.js with the code below:

  4. Run the app: npm start

// Image Carousel - App.js
import React, { useState, useEffect } from 'react';

const images = [
  'https://via.placeholder.com/600x300?text=Slide+1',
  'https://via.placeholder.com/600x300?text=Slide+2',
  'https://via.placeholder.com/600x300?text=Slide+3',
  'https://via.placeholder.com/600x300?text=Slide+4'
];

function App() {
  const [currentIndex, setCurrentIndex] = useState(0);

  // Auto play effect: change slide every 3 seconds
  useEffect(() => {
    const timer = setInterval(() => {
      setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length);
    }, 3000);
    return () => clearInterval(timer);
  }, []);

  // Go to previous slide
  const prevSlide = () => {
    setCurrentIndex((prevIndex) => (prevIndex === 0 ? images.length - 1 : prevIndex - 1));
  };

  // Go to next slide
  const nextSlide = () => {
    setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length);
  };

  return (
    <div style={{ maxWidth: '600px', margin: 'auto', textAlign: 'center', fontFamily: 'Arial' }}>
      <h1>Image Carousel</h1>
      <div style={{ position: 'relative' }}>
        <img
          src={images[currentIndex]}
          alt={`Slide ${currentIndex + 1}`}
          style={{ width: '100%', height: '300px', objectFit: 'cover', borderRadius: '8px' }}
        />

        <button
          onClick={prevSlide}
          style={{
            position: 'absolute',
            top: '50%',
            left: '10px',
            transform: 'translateY(-50%)',
            backgroundColor: 'rgba(0,0,0,0.5)',
            color: 'white',
            border: 'none',
            padding: '10px',
            borderRadius: '50%',
            cursor: 'pointer'
          }}
          aria-label="Previous Slide"
        ><‹>
        </button>

        <button
          onClick={nextSlide}
          style={{
            position: 'absolute',
            top: '50%',
            right: '10px',
            transform: 'translateY(-50%)',
            backgroundColor: 'rgba(0,0,0,0.5)',
            color: 'white',
            border: 'none',
            padding: '10px',
            borderRadius: '50%',
            cursor: 'pointer'
          }}
          aria-label="Next Slide"
        ><›>
        </button>
      </div>

      <div style={{ marginTop: '10px' }}>
        {images.map((_, idx) => (
          <span
            key={idx}
            onClick={() => setCurrentIndex(idx)}
            style={{
              display: 'inline-block',
              width: '12px',
              height: '12px',
              margin: '0 5px',
              backgroundColor: idx === currentIndex ? '#0d6efd' : '#ccc',
              borderRadius: '50%',
              cursor: 'pointer'
            }}
          />
        ))}
      </div>
    </div>
  );
}

export default App;
      

Output:


An image carousel slider that auto-plays every 3 seconds and allows manual navigation via previous/next buttons and clickable dots below the images.

How to Run:


  1. Run: npx create-react-app multi-step-form

  2. Navigate: cd multi-step-form

  3. Replace App.js with the code below:

  4. Run the app: npm start

// Multi-step Form - App.js
import React, { useState } from 'react';

function App() {
  const [step, setStep] = useState(1);
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    age: ''
  });
  const [errors, setErrors] = useState({});

  // Validate current step fields
  const validate = () => {
    let tempErrors = {};
    if (step === 1) {
      if (!formData.name) tempErrors.name = 'Name is required';
      if (!formData.email) {
        tempErrors.email = 'Email is required';
      } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
        tempErrors.email = 'Email is invalid';
      }
    }
    if (step === 2) {
      if (!formData.age) {
        tempErrors.age = 'Age is required';
      } else if (isNaN(formData.age) || formData.age < 1) {
        tempErrors.age = 'Age must be a positive number';
      }
    }
    setErrors(tempErrors);
    return Object.keys(tempErrors).length === 0;
  };

  const nextStep = () => {
    if (validate()) {
      setStep(step + 1);
    }
  };

  const prevStep = () => {
    setStep(step - 1);
  };

  const handleChange = (e) => {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };

  return (
    <div style={{ maxWidth: '400px', margin: 'auto', fontFamily: 'Arial' }}>
      <h1>Multi-step Form</h1>

      <div style={{ marginBottom: '20px' }}>
        Step {step} of 3
        <div style={{ height: '10px', background: '#ccc', borderRadius: '5px', marginTop: '5px' }}>
          <div
            style={{
              width: `${(step / 3) * 100}%`,
              height: '10px',
              background: '#0d6efd',
              borderRadius: '5px'
            }}
          />
        </div>
      </div>

      {step === 1 && (
        <div>
          <label>Name:</label><br />
          <input type="text" name="name" value={formData.name} onChange={handleChange} />
          {errors.name && <div style={{ color: 'red' }}>{errors.name}</div>}
        </div>
      )}

      {step === 2 && (
        <div>
          <label>Email:</label><br />
          <input type="email" name="email" value={formData.email} onChange={handleChange} />
          {errors.email && <div style={{ color: 'red' }}>{errors.email}</div>}
        </div>
      )}

      {step === 3 && (
        <div>
          <label>Age:</label><br />
          <input type="number" name="age" value={formData.age} onChange={handleChange} />
          {errors.age && <div style={{ color: 'red' }}>{errors.age}</div>}
        </div>
      )}

      <div style={{ marginTop: '20px' }}>
        {step > 1 && <button onClick={prevStep}>Previous</button>}
        {step < 3 && <button onClick={nextStep} style={{ marginLeft: '10px' }}>Next</button>}
        {step === 3 && <button onClick={() => alert('Form submitted!')} style={{ marginLeft: '10px' }}>Submit</button>}
      </div>
    </div>
  );
}

export default App;
      

Output:


A multi-step form with validation on each step and a progress bar indicating the current step. Users can navigate between steps and submit the form at the end.

How to Run:


  1. Run: npx create-react-app auth-system

  2. Navigate: cd auth-system

  3. Install dependencies: npm install axios react-router-dom jwt-decode

  4. Set up a backend server to handle JWT authentication (e.g., Express + JWT)

  5. Replace App.js and create relevant components as below:

// User Authentication System - App.js
import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import axios from 'axios';
import jwtDecode from 'jwt-decode';

function Login({ setToken }) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const response = await axios.post('http://localhost:4000/api/login', { email, password });
      const { token } = response.data;
      localStorage.setItem('token', token);
      setToken(token);
      setError('');
    } catch (err) {
      setError('Invalid credentials');
    }
  };

  return (
    <div style={{ maxWidth: '400px', margin: 'auto', fontFamily: 'Arial' }}>
      <h2>Login</h2>
      <form onSubmit={handleSubmit}>
        <input
          type="email"
          placeholder="Email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          required
        /><br />
        <input
          type="password"
          placeholder="Password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          required
        /><br />
        <button type="submit">Login</button>
      </form>
      {error && <div style={{ color: 'red' }}>{error}</div>}
    </div>
  );
}

function Dashboard({ token }) {
  const decoded = jwtDecode(token);

  return (
    <div style={{ fontFamily: 'Arial', padding: '20px' }}>
      <h2>Dashboard</h2>
      <p>Welcome, {decoded.email}!</p>
      <button onClick={() => {
        localStorage.removeItem('token');
        window.location.reload();
      }}>Logout</button>
    </div>
  );
}

function PrivateRoute({ token, children }) {
  return token ? children : <Navigate to="/login" />;
}

function App() {
  const [token, setToken] = useState(localStorage.getItem('token') || '');

  useEffect(() => {
    if (token) {
      try {
        jwtDecode(token);
      } catch {
        setToken('');
        localStorage.removeItem('token');
      }
    }
  }, [token]);

  return (
    <Router>
      <Routes>
        <Route path="/login" element=<Login setToken={setToken} /> />
        <Route
          path="/dashboard"
          element=<PrivateRoute token={token}><Dashboard token={token} /></PrivateRoute>
        />
        <Route path="*" element=<Navigate to="/dashboard" /> />
      </Routes>
    </Router>
  );
}

export default App;
      

Output:


A simple React user authentication system that allows login using JWT tokens and protects dashboard routes, redirecting unauthenticated users to login.

How to Run:


  1. Run: npx create-react-app realtime-editor

  2. Navigate: cd realtime-editor

  3. Install Socket.io Client: npm install socket.io-client

  4. Set up a backend server with Socket.io for real-time syncing

  5. Replace App.js with the code below:

// Real-time Collaboration Editor - App.js
import React, { useState, useEffect, useRef } from 'react';
import io from 'socket.io-client';

const socket = io('http://localhost:4000'); // Backend Socket.io server

function App() {
  const [text, setText] = useState('');
  const textAreaRef = useRef(null);

  useEffect(() => {
    socket.on('updateText', (newText) => {
      setText(newText);
    });

    return () => {
      socket.off('updateText');
    };
  }, []);

  const handleChange = (e) => {
    setText(e.target.value);
    socket.emit('sendText', e.target.value);
  };

  return (
    <div style={{ maxWidth: '600px', margin: 'auto', padding: '20px', fontFamily: 'Arial' }}>
      <h2>Real-time Collaboration Editor</h2>
      <textarea
        ref={textAreaRef}
        value={text}
        onChange={handleChange}
        rows="15"
        cols="70"
        placeholder="Start typing..."
        style={{ fontSize: '16px', padding: '10px' }}
      />
    </div>
  );
}

export default App;
      

Output:


A simple text editor where multiple users can type simultaneously and see real-time updates synced via Socket.io.

How to Run Your React Real-time Collaboration Editor Project Step-by-Step

1. Set up your React frontend

Open your terminal/command prompt.

Run this command to create the React app folder:

npx create-react-app realtime-editor

Navigate inside the folder:

cd realtime-editor

Install the Socket.io client library:

npm install socket.io-client

Replace the src/App.js file content with your React code.

Run the React app with:

npm start

This will open your React app in the browser, typically at http://localhost:3000.

2. Set up the backend Socket.io server (needed for real-time syncing)

Create a simple Node.js server:

In a separate folder (or inside your React project folder but outside src), create a new file called server.js.

Add this simple backend code:

// server.js
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
  cors: {
    origin: '*',
  }
});

let currentText = '';

io.on('connection', (socket) => {
  console.log('New client connected');

  // Send current text to new clients
  socket.emit('updateText', currentText);

  socket.on('sendText', (text) => {
    currentText = text;
    socket.broadcast.emit('updateText', text);
  });

  socket.on('disconnect', () => {
    console.log('Client disconnected');
  });
});

const PORT = 4000;
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));

Run this backend server with:

npm init -y
npm install express socket.io
node server.js

This will start the backend Socket.io server on http://localhost:4000.

3. How it works

Your React app connects to the backend Socket.io server at http://localhost:4000.

When you type in the editor in one browser window, it sends the text to the server, which broadcasts it to all other connected clients.

This enables multiple users to see real-time synchronized text.

Summary

Step Command/Action
Create React appnpx create-react-app realtime-editor
Install client librarynpm install socket.io-client
Replace App.js codePaste your React component code
Start React appnpm start
Setup backend server fileCreate server.js with backend code
Install backend packagesnpm install express socket.io
Run backend servernode server.js

Why can't you run this directly in a plain HTML file?

  • React apps need to be compiled/bundled by tools like create-react-app and run with a Node.js environment.
  • Socket.io needs a backend server to handle WebSocket connections.
  • Plain HTML does not support these features.

Project Overview:


This project builds an RSS Feed Reader using React that fetches RSS feeds (news, blogs, etc.) from a public RSS URL, converts them to JSON via a free API, and displays the latest feed items.
Users can filter the displayed news items by keyword.

How to Run:


  1. Make sure you have Node.js installed. If not, download and install from nodejs.org.

  2. Open your terminal and run: npx create-react-app rss-feed-reader

  3. Navigate to the project folder: cd rss-feed-reader

  4. Replace the content of src/App.js with the React code below.

  5. Run the app with: npm start

React Code (App.js):


// RSS Feed Reader - App.js
import React, { useState, useEffect } from 'react';

function App() {
  const [feedItems, setFeedItems] = useState([]);
  const [filter, setFilter] = useState('');

  useEffect(() => {
    // Sample RSS feed URL (BBC News)
    const rssUrl = 'http://feeds.bbci.co.uk/news/rss.xml';

    // Use a free API to convert RSS XML to JSON
    const apiUrl = `https://api.rss2json.com/v1/api.json?rss_url=${encodeURIComponent(rssUrl)}`;

    fetch(apiUrl)
      .then(response => response.json())
      .then(data => {
        if (data.status === 'ok') {
          setFeedItems(data.items);
        } else {
          console.error('Failed to fetch feed');
        }
      })
      .catch(error => console.error('Error fetching feed:', error));
  }, []);

  // Filter feed items by title or description containing the filter keyword (case-insensitive)
  const filteredItems = feedItems.filter(item => 
    item.title.toLowerCase().includes(filter.toLowerCase()) || 
    item.description.toLowerCase().includes(filter.toLowerCase())
  );

  return (
    <div style={{ padding: '20px', fontFamily: 'Arial', maxWidth: '800px', margin: 'auto' }}>
      <h1>RSS Feed Reader</h1>
      <input
        type="text"
        placeholder="Filter news by keyword..."
        value={filter}
        onChange={e => setFilter(e.target.value)}
        style={{ width: '100%', padding: '8px', marginBottom: '20px', fontSize: '16px' }}
      />

      {filteredItems.length === 0 ? (
        <p>No news found matching your filter.</p>
      ) : (
        filteredItems.map((item, index) => (
          <div key={index} style={{ marginBottom: '20px', borderBottom: '1px solid #ccc', paddingBottom: '10px' }}>
            <h3><a href={item.link} target="_blank" rel="noopener noreferrer">{item.title}</a></h3>
            <p>{item.pubDate}</p>
            <p>{item.description.replace(/<[^>]+>/g, '')}</p>
          </div>
        ))
      )}
    </div>
  );
}

export default App;
      

Output:


This will show a list of news articles from the BBC RSS feed. You can filter articles by typing keywords in the input box. Clicking a news title opens the article in a new tab.

Notes:


- The free API used here (rss2json.com) converts RSS XML to JSON to make it easy to work with in JavaScript.
- You can replace the rssUrl with any valid RSS feed URL.
- For production, consider setting up your own RSS-to-JSON proxy for reliability.

Project Overview:


This project is a Crypto Price Tracker built with React. It fetches current prices and trends of popular cryptocurrencies (like Bitcoin, Ethereum, etc.) from a public API and displays them in a clean interface.
Users get updated prices and percentage changes over the last 24 hours.

How to Run:


  1. Ensure Node.js is installed on your system. Download from nodejs.org if needed.

  2. Open a terminal and create a new React app:
    npx create-react-app crypto-price-tracker

  3. Navigate into the project folder:
    cd crypto-price-tracker

  4. Replace the content of src/App.js with the React code below.

  5. Start the development server:
    npm start

React Code (App.js):


// Crypto Price Tracker - App.js
import React, { useEffect, useState } from 'react';

function App() {
  const [coins, setCoins] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // Fetch top 10 cryptocurrencies from CoinGecko API
    fetch('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=10&page=1&sparkline=false')
      .then(response => response.json())
      .then(data => {
        setCoins(data);
        setLoading(false);
      })
      .catch(error => {
        console.error('Error fetching crypto data:', error);
        setLoading(false);
      });
  }, []);

  if (loading) {
    return <div style={{ padding: '20px', fontFamily: 'Arial' }}>Loading data...</div>;
  }

  return (
    <div style={{ maxWidth: '800px', margin: 'auto', padding: '20px', fontFamily: 'Arial' }}>
      <h1>Crypto Price Tracker</h1>
      <table style={{ width: '100%', borderCollapse: 'collapse' }}>
        <thead>
          <tr style={{ borderBottom: '2px solid #333' }}>
            <th style={{ textAlign: 'left', padding: '10px' }}>Name</th>
            <th style={{ textAlign: 'right', padding: '10px' }}>Price (USD)</th>
            <th style={{ textAlign: 'right', padding: '10px' }}>24h Change</th>
          </tr>
        </thead>
        <tbody>
          {coins.map(coin => (
            <tr key={coin.id} style={{ borderBottom: '1px solid #ccc' }}>
              <td style={{ padding: '10px', display: 'flex', alignItems: 'center' }}>
                <img src={coin.image} alt={coin.name} style={{ width: '24px', height: '24px', marginRight: '10px' }} />
                {coin.name}
              </td>
              <td style={{ padding: '10px', textAlign: 'right' }}>${coin.current_price.toLocaleString()}</td>
              <td style={{ padding: '10px', textAlign: 'right', color: coin.price_change_percentage_24h > 0 ? 'green' : 'red' }}>
                {coin.price_change_percentage_24h.toFixed(2)}%
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

export default App;
      

Output:


Displays a table listing the top 10 cryptocurrencies by market cap, showing each coin's name (with logo), current price in USD, and 24-hour price change percentage.

Notes:


- Uses CoinGecko's free public API (coingecko.com/api).
- Prices update only on page load; you can enhance it by adding periodic refresh.
- You can customize to track different coins or show more data.

How to Run:


  1. Run: npx create-react-app blog-comments

  2. Navigate: cd blog-comments

  3. Replace App.js with the code below:

  4. Run the app: npm start

// Blog Comments Section - App.js
import React, { useState } from 'react';

function Comment({ comment, addReply, like, dislike }) {
  const [showReply, setShowReply] = useState(false);
  const [replyText, setReplyText] = useState('');

  return (
    <div style={{ marginLeft: comment.level * 20, border: '1px solid #ccc', padding: '10px', marginTop: '10px' }}>
      <p>{comment.text}</p>
      <button onClick={() => like(comment.id)}>Like ({comment.likes})</button>
      <button onClick={() => dislike(comment.id)}>Dislike ({comment.dislikes})</button>
      <button onClick={() => setShowReply(!showReply)}>Reply</button>
      {showReply && (
        <div>
          <textarea
            rows="2"
            cols="50"
            value={replyText}
            onChange={(e) => setReplyText(e.target.value)}
            placeholder="Write your reply..."
          /><br />
          <button onClick={() => { addReply(comment.id, replyText); setReplyText(''); setShowReply(false); }}>Submit Reply</button>
        </div>
      )}
      {comment.replies.map(reply => (
        <Comment key={reply.id} comment={reply} addReply={addReply} like={like} dislike={dislike} />
      ))}
    </div>
  );
}

function App() {
  const [comments, setComments] = useState([]);
  const [commentText, setCommentText] = useState('');

  const addComment = () => {
    if (commentText.trim() === '') return;
    const newComment = {
      id: Date.now(),
      text: commentText,
      likes: 0,
      dislikes: 0,
      replies: [],
      level: 0
    };
    setComments([...comments, newComment]);
    setCommentText('');
  };

  const addReply = (parentId, text) => {
    if (text.trim() === '') return;

    const addReplyRecursive = (commentsList) => {
      return commentsList.map(comment => {
        if (comment.id === parentId) {
          const reply = {
            id: Date.now(),
            text,
            likes: 0,
            dislikes: 0,
            replies: [],
            level: comment.level + 1
          };
          return { ...comment, replies: [...comment.replies, reply] };
        }
        return { ...comment, replies: addReplyRecursive(comment.replies) };
      });
    };

    setComments(addReplyRecursive(comments));
  };

  const like = (id) => {
    const likeRecursive = (commentsList) => {
      return commentsList.map(comment => {
        if (comment.id === id) {
          return { ...comment, likes: comment.likes + 1 };
        }
        return { ...comment, replies: likeRecursive(comment.replies) };
      });
    };
    setComments(likeRecursive(comments));
  };

  const dislike = (id) => {
    const dislikeRecursive = (commentsList) => {
      return commentsList.map(comment => {
        if (comment.id === id) {
          return { ...comment, dislikes: comment.dislikes + 1 };
        }
        return { ...comment, replies: dislikeRecursive(comment.replies) };
      });
    };
    setComments(dislikeRecursive(comments));
  };

  return (
    <div style={{ padding: 20, fontFamily: 'Arial' }}>
      <h1>Blog Comments Section</h1>
      <textarea
        rows="4"
        cols="60"
        placeholder="Write a comment..."
        value={commentText}
        onChange={(e) => setCommentText(e.target.value)}
      /><br />
      <button onClick={addComment}>Add Comment</button>

      <div>
        {comments.map(comment => (
          <Comment
            key={comment.id}
            comment={comment}
            addReply={addReply}
            like={like}
            dislike={dislike}
          />
        ))}
      </div>
    </div>
  );
}

export default App;
      

Output:


A blog comments section allowing nested replies, likes, and dislikes with a clean threaded view.

How to Run:


  1. Run: npx create-react-app event-booking-calendar

  2. Navigate: cd event-booking-calendar

  3. Install dependencies: npm install react-calendar react-toastify

  4. Replace App.js with the code below.

  5. Start the app: npm start

// Event Booking Calendar - App.js
import React, { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

function App() {
  const [date, setDate] = useState(new Date());
  const [events, setEvents] = useState([]);

  const addEvent = () => {
    const eventTitle = prompt('Enter event title:');
    if (eventTitle) {
      setEvents([...events, { date: date.toDateString(), title: eventTitle }]);
      toast.success('Event added!');
    }
  };

  const eventsForDate = events.filter(e => e.date === date.toDateString());

  return (
    <div style={{ maxWidth: '600px', margin: 'auto', padding: '20px', fontFamily: 'Arial' }}>
      <h2>Event Booking Calendar</h2>
      <Calendar
        onChange={setDate}
        value={date}
      />
      <h3>Events on {date.toDateString()}</h3>
      <ul>
        {eventsForDate.length === 0 ? (
          <li>No events</li>
        ) : (
          eventsForDate.map((event, index) => <li key={index}>{event.title}</li>)
        )}
      </ul>
      <button onClick={addEvent}>Add Event</button>
      <ToastContainer />
    </div>
  );
}

export default App;
      

Output:


A calendar UI to select dates, add events with reminders, and view events by date.

How to Run:


  1. Run: npx create-react-app expense-dashboard

  2. Navigate: cd expense-dashboard

  3. Install dependencies: npm install recharts

  4. Replace App.js with the code below.

  5. Start the app: npm start

// Expense Dashboard with Graphs - App.js
import React, { useState } from 'react';
import { BarChart, Bar, XAxis, YAxis, Tooltip, CartesianGrid, Legend } from 'recharts';

const initialData = [
  { month: 'Jan', expenses: 400 },
  { month: 'Feb', expenses: 300 },
  { month: 'Mar', expenses: 500 },
  { month: 'Apr', expenses: 200 },
  { month: 'May', expenses: 700 },
  { month: 'Jun', expenses: 600 },
];

function App() {
  const [data, setData] = useState(initialData);

  return (
    <div style={{ maxWidth: '700px', margin: 'auto', padding: '20px', fontFamily: 'Arial' }}>
      <h2>Expense Dashboard</h2>
      <BarChart width={600} height={300} data={data}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="month" />
        <YAxis />
        <Tooltip />
        <Legend />
        <Bar dataKey="expenses" fill="#8884d8" />
      </BarChart>
      <h3>Expenses by Month</h3>
      <ul>
        {data.map((item, idx) => (
          <li key={idx}>{item.month}: ${item.expenses}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;
      

Output:


A dashboard displaying monthly expenses visually via a bar chart with a list summary below.

How to Run:


  1. Run: npx create-react-app event-booking-calendar

  2. Navigate: cd event-booking-calendar

  3. Install dependencies: npm install react-calendar react-toastify

  4. Replace App.js content with the code below.

  5. Start the app: npm start

// Event Booking Calendar - App.js
import React, { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

function App() {
  const [date, setDate] = useState(new Date());
  const [events, setEvents] = useState([]);

  const addEvent = () => {
    const eventTitle = prompt('Enter event title:');
    if (eventTitle) {
      setEvents([...events, { date: date.toDateString(), title: eventTitle }]);
      toast.success('Event added!');
    }
  };

  const eventsForDate = events.filter(e => e.date === date.toDateString());

  return (
    <div style={{ maxWidth: '600px', margin: 'auto', padding: '20px', fontFamily: 'Arial' }}>
      <h2>Event Booking Calendar</h2>
      <Calendar
        onChange={setDate}
        value={date}
      />
      <h3>Events on {date.toDateString()}</h3>
      <ul>
        {eventsForDate.length === 0 ? (
          <li>No events</li>
        ) : (
          eventsForDate.map((event, index) => <li key={index}>{event.title}</li>)
        )}
      </ul>
      <button onClick={addEvent}>Add Event</button>
      <ToastContainer />
    </div>
  );
}

export default App;
      

Output:


A calendar interface where users can select dates, add events with reminders, and view all events scheduled for the selected date in real time.