📄Assignments Of Class 11
Conditional useEffect and Cleanup
Assignment 1:Create a React component that logs "Component mounted" once when the component first renders.
Solution:
import React, { useEffect } from 'react';
function LogOnMount() {
useEffect(() => {
console.log('Component mounted');
}, []); // Empty dependency array ensures it runs once
return <div>Check console for message</div>;
}
export default LogOnMount;
Explanation:
Empty dependency array [] causes the effect to run only once after the first
render.
Assignment 2:Create a component with a counter state. Use useEffect to log the current counter value whenever it changes.
Solution:
import React, { useState, useEffect } from 'react';
function CounterLogger() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`Count changed: ${count}`);
}, [count]); // Effect runs whenever `count` changes
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default CounterLogger;
Explanation:
Effect depends on count, so runs only when count updates.
Assignment 3:Create a component that sets a timer using setInterval inside useEffect. Log "Tick" every second. Make sure to clean up the timer on component unmount.
Solution:
import React, { useEffect } from 'react';
function Timer() {
useEffect(() => {
const intervalId = setInterval(() => {
console.log('Tick');
}, 1000);
return () => {
clearInterval(intervalId); // Cleanup the timer on unmount
console.log('Timer cleaned up');
};
}, []);
return <div>Open console to see ticks every second</div>;
}
export default Timer;
Explanation:
Cleanup function clears the interval when component unmounts to avoid memory
leaks.
Assignment 4:Create a joke-fetching component that fetches a joke only once when the component mounts, and displays it.
Solution:
import React, { useState, useEffect } from 'react';
function JokeFetcher() {
const [joke, setJoke] = useState('');
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://official-joke-api.appspot.com/random_joke')
.then(res => res.json())
.then(data => {
setJoke(data.setup + ' - ' + data.punchline);
setLoading(false);
})
.catch(() => {
setJoke('Failed to fetch joke');
setLoading(false);
});
}, []);
return <div>{loading ? 'Loading...' : joke}</div>;
}
export default JokeFetcher;
Explanation:
Empty dependency array ensures joke fetch runs once on mount.
Assignment 5:Enhance the joke-fetching component by adding a button to fetch a new joke on demand.
Solution:
import React, { useState, useEffect } from 'react';
function JokeFetcherWithButton() {
const [joke, setJoke] = useState('');
const [loading, setLoading] = useState(true);
const [fetchTrigger, setFetchTrigger] = useState(0);
useEffect(() => {
setLoading(true);
fetch('https://official-joke-api.appspot.com/random_joke')
.then(res => res.json())
.then(data => {
setJoke(data.setup + ' - ' + data.punchline);
setLoading(false);
})
.catch(() => {
setJoke('Failed to fetch joke');
setLoading(false);
});
}, [fetchTrigger]);
return (
<div>
{loading ? 'Loading...' : joke}
<button onClick={() => setFetchTrigger(prev => prev +
1)}>Fetch New Joke</button>
</div>
);
}
export default JokeFetcherWithButton;
Explanation:
Adding fetchTrigger state as a dependency causes effect to re-run each time the
button is clicked.
Assignment 6:Create a component that listens for window resize events and updates the state with the current window width. Ensure you clean up the event listener on unmount.
Solution:
import React, { useState, useEffect } from 'react';
function WindowWidthTracker() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return <div>Window width: {width}px</div>;
}
export default WindowWidthTracker;
Explanation:
Cleanup removes the event listener when the component unmounts to prevent
memory leaks.
Assignment 7:Modify the joke-fetching component so that if the component unmounts while the fetch is ongoing, it cancels setting the state (simulate cleanup).
Solution:
import React, { useState, useEffect } from 'react';
function SafeJokeFetcher() {
const [joke, setJoke] = useState('');
const [loading, setLoading] = useState(true);
useEffect(() => {
let isMounted = true; // Track if component is mounted
fetch('https://official-joke-api.appspot.com/random_joke')
.then(res => res.json())
.then(data => {
if (isMounted) { // Only update state
if still mounted
setJoke(data.setup + ' - ' + data.punchline);
setLoading(false);
}
})
.catch(() => {
if (isMounted) {
setJoke('Failed to fetch joke');
setLoading(false);
}
});
return () => {
isMounted = false; // Cleanup toggles flag on unmount
};
}, []);
return <div>{loading ? 'Loading...' : joke}</div>;
}
export default SafeJokeFetcher;
Explanation:
isMounted flag prevents state updates if component unmounts mid-fetch.
Assignment 8:Create a component that fetches data from an API only when a checkbox is checked. Use the dependency array correctly to control this behavior.
Solution:
import React, { useState, useEffect } from 'react';
function ConditionalFetch() {
const [checked, setChecked] = useState(false);
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (checked) {
setLoading(true);
fetch('https://official-joke-api.appspot.com/random_joke')
.then(res => res.json())
.then(data => {
setData(data.setup + ' - ' + data.punchline);
setLoading(false);
});
}
}, [checked]);
return (
<div>
<label>
<input
type="checkbox"
checked={checked}
onChange={() =>
setChecked(!checked)}
/>
Fetch Joke
</label>
<div>{loading ? 'Loading...' : data}</div>
</div>
);
}
export default ConditionalFetch;
Explanation:
Effect runs only when checked becomes true; no fetch if unchecked.
Assignment 9:Build a component that toggles a dark mode class on the body element using useEffect. Clean up the class on unmount.
Solution:
import React, { useState, useEffect } from 'react';
function DarkModeToggle() {
const [darkMode, setDarkMode] = useState(false);
useEffect(() => {
if (darkMode) {
document.body.classList.add('dark-mode');
} else {
document.body.classList.remove('dark-mode');
}
return () => {
document.body.classList.remove('dark-mode'); // Cleanup on unmount
};
}, [darkMode]);
return (
<button onClick={() => setDarkMode(prev => !prev)}>
Toggle Dark Mode
</button>
);
}
export default DarkModeToggle;
Explanation:
Cleanup removes the class on unmount to prevent side effects lingering.
Assignment 10:Create a component that fetches a joke repeatedly every 10 seconds using setInterval inside useEffect. Clean up the interval properly on unmount.
Solution:
import React, { useState, useEffect } from 'react';
function AutoJokeFetcher() {
const [joke, setJoke] = useState('');
useEffect(() => {
function fetchJoke() {
fetch('https://official-joke-api.appspot.com/random_joke')
.then(res => res.json())
.then(data => setJoke(data.setup + '
- ' + data.punchline));
}
fetchJoke(); // Fetch immediately on mount
const intervalId = setInterval(fetchJoke, 10000); // Fetch every 10
seconds
return () => clearInterval(intervalId); // Cleanup on unmount
}, []);
return <div>{joke || 'Loading...'}</div>;
}
export default AutoJokeFetcher;
Explanation:
setInterval schedules repeated fetches; cleanup clears interval on unmount.
