Understanding component lifecycle phases and how to respond to them
Every React component goes through a lifecycle: it’s created (mounted), updated, and eventually removed (unmounted). Understanding the component lifecycle helps you manage side effects, clean up resources, and optimize performance.
The dependency array controls when the effect runs:
Copy
Ask AI
// Runs after every renderuseEffect(() => { console.log('Rendered');});// Runs only once after mountuseEffect(() => { console.log('Component mounted');}, []);// Runs after mount and when dependencies changeuseEffect(() => { console.log('count or name changed');}, [count, name]);
Rules of Hooks: The useEffect Hook must be called at the top level of your component. Don’t call it inside conditions, loops, or nested functions. React relies on the order of Hook calls to track state correctly.
useLayoutEffect is similar to useEffect but fires synchronously after all DOM mutations, before the browser paints:
Copy
Ask AI
import { useLayoutEffect, useRef } from 'react';function Tooltip() { const ref = useRef(null); useLayoutEffect(() => { // Measure DOM and update position before paint const { height } = ref.current.getBoundingClientRect(); ref.current.style.marginTop = `-${height}px`; }, []); return <div ref={ref}>Tooltip content</div>;}
When to use useLayoutEffect: Use it when you need to read layout information (like scroll position or element size) and synchronously make changes before the browser paints. For most cases, useEffect is preferred.
Class components have explicit lifecycle methods. While function components with Hooks are now preferred, understanding class lifecycle methods is useful for maintaining existing code.
class UserProfile extends Component { componentDidUpdate(prevProps, prevState) { // Called after component updates // Compare previous and current props/state if (this.props.userId !== prevProps.userId) { this.loadUser(this.props.userId); } } shouldComponentUpdate(nextProps, nextState) { // Return false to prevent unnecessary re-renders // PureComponent does this automatically with shallow comparison return ( nextProps.userId !== this.props.userId || nextState.user !== this.state.user ); } render() { return <div>{this.state.user?.name}</div>; }}
According to the React source code in ReactBaseClasses.js, forceUpdate() will not invoke shouldComponentUpdate, but it will invoke componentWillUpdate and componentDidUpdate.