1. Implement a Counter using useState
Solution:
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}
export default Counter;
✅ Uses useState to manage counter state
✅ Updates the count on button click
2. Fetch Data from an API using useEffect
Solution:
import React, { useState, useEffect } from "react";
function FetchData() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((json) => {
setData(json);
setLoading(false);
})
.catch((error) => console.error("Error fetching data:", error));
}, []);
return (
<div>
<h1>Posts</h1>
{loading ? <p>Loading...</p> : data.slice(0, 5).map((post) => <p key={post.id}>{post.title}</p>)}
</div>
);
}
export default FetchData;
✅ Uses useEffect to fetch data when the component mounts
✅ Handles loading state
3. Implement a Simple To-Do List in React
Solution:
import React, { useState } from "react";
function TodoList() {
const [tasks, setTasks] = useState([]);
const [task, setTask] = useState("");
const addTask = () => {
if (task.trim() !== "") {
setTasks([...tasks, task]);
setTask("");
}
};
const removeTask = (index) => {
setTasks(tasks.filter((_, i) => i !== index));
};
return (
<div>
<h1>To-Do List</h1>
<input
type="text"
value={task}
onChange={(e) => setTask(e.target.value)}
placeholder="Add a task"
/>
<button onClick={addTask}>Add</button>
<ul>
{tasks.map((t, index) => (
<li key={index}>
{t} <button onClick={() => removeTask(index)}>Remove</button>
</li>
))}
</ul>
</div>
);
}
export default TodoList;
✅ Uses useState to manage the task list
✅ Allows adding and removing tasks
4. Create a Custom React Hook (useLocalStorage)
Solution:
import { useState, useEffect } from "react";
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const storedValue = localStorage.getItem(key);
return storedValue ? JSON.parse(storedValue) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
// Example usage in a component
function CounterWithLocalStorage() {
const [count, setCount] = useLocalStorage("count", 0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}
export default CounterWithLocalStorage;
✅ Stores data in _localStorage _and persists after page refresh
✅ Custom Hook _useLocalStorage _manages local storage state
- Optimize a React Component to Prevent Unnecessary Re-Renders Solution using React.memo and useCallback
import React, { useState, useCallback } from "react";
const Button = React.memo(({ onClick, label }) => {
console.log(`Rendering button: ${label}`);
return <button onClick={onClick}>{label}</button>;
});
function OptimizedComponent() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const increment = useCallback(() => setCount(count + 1), [count]);
return (
<div>
<h1>Count: {count}</h1>
<Button onClick={increment} label="Increment" />
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Type something..."
/>
</div>
);
}
export default OptimizedComponent;
✅ React.memo() prevents re-rendering the Button component unless props change
✅ useCallback() ensures increment function is not re-created on every render
Top comments (0)