React’s component lifecycle refers to the stages a component goes through during its existence, from its creation to its removal from the DOM. This lifecycle allows developers to hook into specific moments to execute custom logic, optimize performance, and manage resources effectively.
Lifecycle Phases
React components have three main lifecycle phases:
- Mounting: The component is created and added to the DOM.
- Updating: The component re-renders due to changes in state or props.
- Unmounting: The component is removed from the DOM.
Lifecycle in Class Components
Lifecycle methods in class components allow precise control over component behavior during each phase.
1. Mounting Phase
These methods are called when the component is created and inserted into the DOM:
constructor()
- Used for initializing state and binding event handlers.
- Example:
constructor(props) { super(props); this.state = { count: 0 }; }
static getDerivedStateFromProps(props, state)
- Updates state based on changes in props.
- Rarely used; prefer state management in functional components.
- Example:
static getDerivedStateFromProps(props, state) { if (props.value !== state.value) { return { value: props.value }; } return null; }
render()
- Renders the component’s UI.
- Example:
render() { return <h1>Hello, React!</h1>; }
componentDidMount()
- Executes after the component is mounted.
- Commonly used for API calls or DOM manipulations.
- Example:
componentDidMount() { fetchData().then(data => this.setState({ data })); }
2. Updating Phase
These methods are called when the component updates (e.g., state or props change):
static getDerivedStateFromProps(props, state)
- Same as during mounting, used to update state based on props.
shouldComponentUpdate(nextProps, nextState)
- Determines whether the component should re-render.
- Example:
shouldComponentUpdate(nextProps, nextState) { return nextState.count !== this.state.count; }
-
render()
- Re-renders the component when state or props change.
getSnapshotBeforeUpdate(prevProps, prevState)
- Captures information (e.g., scroll position) before the DOM is updated.
- Example:
getSnapshotBeforeUpdate(prevProps, prevState) { return window.scrollY; }
componentDidUpdate(prevProps, prevState, snapshot)
- Executes after the component updates.
- Useful for performing side effects or working with the snapshot.
- Example:
componentDidUpdate(prevProps, prevState, snapshot) { if (snapshot !== null) { console.log("Previous scroll position:", snapshot); } }
3. Unmounting Phase
These methods are called when the component is removed from the DOM:
componentWillUnmount()
- Used to clean up resources (e.g., timers, subscriptions).
- Example:
componentWillUnmount() { clearInterval(this.timer); }
Lifecycle in Functional Components
Modern React prefers functional components with Hooks to handle lifecycle events. Here’s how lifecycle functionality maps to Hooks:
1. Mounting
useEffect(() => { ... }, [])
- Executes once after the component mounts.
- Example:
useEffect(() => { console.log("Component mounted"); }, []);
2. Updating
useEffect(() => { ... })
- Executes after every render (state or props change).
- Example:
useEffect(() => { console.log("Component updated"); });
useEffect(() => { ... }, [dependencies])
- Executes only when specified dependencies change.
- Example:
useEffect(() => { console.log("Count changed:", count); }, [count]);
3. Unmounting
- Cleanup in
useEffect
- Executes before the component unmounts.
- Example:
useEffect(() => { const timer = setInterval(() => console.log("Tick"), 1000); return () => { clearInterval(timer); // Cleanup console.log("Component unmounted"); }; }, []);
Lifecycle Overview
- Mounting Phase:
constructor
→getDerivedStateFromProps
→render
→componentDidMount
- Updating Phase:
getDerivedStateFromProps
→shouldComponentUpdate
→render
→getSnapshotBeforeUpdate
→componentDidUpdate
- Unmounting Phase:
componentWillUnmount
Best Practices
- Prefer functional components with Hooks for new projects.
- Use
useEffect
for side effects like data fetching or subscriptions. - Optimize performance by leveraging memoization (e.g.,
React.memo
,useMemo
,useCallback
). - Avoid unnecessary updates by managing dependencies carefully in
useEffect
.