React Interview Questions (Part 2): Component Lifecycle & Hooks
What are the differences between componentDidMount
, componentDidUpdate
, and componentWillUnmount
in class components?
componentDidMount
, componentDidUpdate
, and componentWillUnmount
are lifecycle methods in React class components that are invoked at different stages of a component's lifecycle:
componentDidMount
: This method is called once, immediately after the component is mounted to the DOM (right after the initial render). It's commonly used to initialize data (e.g., making API calls) or set up subscriptions (e.g., event listeners).componentDidUpdate
: This method is called after every update (re-render) of the component, except for the initial render. It can be used to perform actions based on changes to props or state, such as fetching new data or updating the DOM.componentWillUnmount
: This method is invoked right before a component is removed (unmounted) from the DOM. Itโs typically used to clean up resources, such as cancelling API requests or removing event listeners.
How does React manage the component lifecycle in function components using hooks?
In function components, React manages the lifecycle through hooks, primarily useState
, useReducer
, and useEffect
:
State Updates (
useState
anduseReducer
): When the state is updated usinguseState
oruseReducer
, React triggers a re-render of the component. During this re-render, a new virtual DOM is created, which is compared to the previous virtual DOM (using a process called "reconciliation"). React then makes the necessary updates to the actual DOM, minimizing changes to only what is required, improving performance.Effects (
useEffect
): TheuseEffect
hook is used to handle side effects in function components. You can control when the effect runs by specifying dependencies in the dependency array. Whenever the dependencies change, React re-runs the effect. This is useful for actions like data fetching, DOM manipulation, or subscribing/unsubscribing from services. By managing side effects this way, React ensures that the UI stays in sync with state and prop changes.
What is the useRef
hook used for?
The useRef
hook in React is primarily used for two purposes:
- Accessing and Manipulating DOM Elements:
useRef
allows you to access a DOM element and persist a reference to it across renders without triggering a re-render. It's useful for tasks like focusing an input, controlling media, or manipulating elements. UnlikeuseState
, changing auseRef
value doesn't cause a re-render.
Example:
function InputFocus() {
const inputRef = useRef();
useEffect(() => {
inputRef.current.focus(); // Focuses the input after the component mounts
}, []);
return <input ref={inputRef} />;
}
- Storing Mutable Values Across Renders:
useRef
can also be used to store any mutable value that persists across renders but doesn't trigger a re-render when updated. This is useful for keeping track of things like timers, previous values, or any value that doesnโt need to cause a re-render when it changes.
Example:
function Timer() {
const timerId = useRef();
const startTimer = () => {
timerId.current = setInterval(() => {
console.log('Timer running...');
}, 1000);
};
const stopTimer = () => {
clearInterval(timerId.current);
};
return (
<div>
<button onClick={startTimer}>Start</button>
<button onClick={stopTimer}>Stop</button>
</div>
);
}
What are custom hooks, and how do you create one?
In React, custom hooks allow you to extract and reuse logic between components, helping to keep your code more modular and maintainable. Custom hooks are simply JavaScript functions that can call other hooks like useState
, useEffect
, or any other React hooks, and they follow the convention of naming with a use
prefix.
Creating a Custom Hook: A custom hook is created by defining a function that bundles logic (like state management or side effects) and can be shared across components. For example, if you want to reuse a data-fetching logic in multiple components, you can encapsulate it into a custom hook.
function useFetchData(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchData() {
const response = await fetch(url);
const result = await response.json();
setData(result);
setLoading(false);
}
fetchData();
}, [url]);
return { data, loading };
}
In this example, the useFetchData
custom hook fetches data from a URL and can be reused across different components. You call this custom hook just like you would call a built-in hook:
function MyComponent() {
const { data, loading } = useFetchData('https://api.example.com/data');
return loading ? <p>Loading...</p> : <p>{JSON.stringify(data)}</p>;
}
What is React.memo
, and when should you use it?
React.memo
is a higher-order component used for performance optimization. It prevents unnecessary re-renders by memoizing a component's output. When you wrap a component with React.memo
, React will only re-render the component if its props change. If the props remain the same, the component will skip re-rendering, thus improving performance in situations where re-renders are costly.
Example:
const MyComponent = React.memo(function MyComponent({ name }) {
return <div>{name}</div>;
});
In this example, MyComponent
will only re-render if the name
prop changes.
Subscribe to my newsletter
Read articles from Yusuf Uysal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Yusuf Uysal
Yusuf Uysal
๐๐ฟ๐ถ๐๐ฒ๐ป ๐๐ฟ๐ผ๐ป๐๐ฒ๐ป๐ฑ ๐๐ฒ๐๐ฒ๐น๐ผ๐ฝ๐ฒ๐ฟ with extensive experience in JavaScript, React.js, and Next.js. I help companies enhance user engagement and deliver high-performance web applications that are responsive, accessible, and visually appealing. Beyond my technical skills, I am a ๐ฐ๐ผ๐น๐น๐ฎ๐ฏ๐ผ๐ฟ๐ฎ๐๐ถ๐๐ฒ ๐๐ฒ๐ฎ๐บ ๐ฝ๐น๐ฎ๐๐ฒ๐ฟ who thrives in environments that value continuous learning and innovation. I enjoy projects where I can leverage my expertise in ๐ฟ๐ฒ๐๐ฝ๐ผ๐ป๐๐ถ๐๐ฒ ๐ฑ๐ฒ๐๐ถ๐ด๐ป, ๐ฏ๐ฟ๐ผ๐๐๐ฒ๐ฟ ๐ฐ๐ผ๐บ๐ฝ๐ฎ๐๐ถ๐ฏ๐ถ๐น๐ถ๐๐, ๐ฎ๐ป๐ฑ ๐๐ฒ๐ฏ ๐ฝ๐ฒ๐ฟ๐ณ๐ผ๐ฟ๐บ๐ฎ๐ป๐ฐ๐ฒ to deliver seamless user experiences. I get excited about opportunities where I can contribute to creating dynamic, user-focused applications while working closely with cross-functional teams to drive impactful results. I love connecting with new people, and you can reach me at yusufuysal.dev@gmail.com.