Suggest an editImprove this articleRefine the answer for “Class vs function component lifecycle”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)Class components manage the lifecycle through **separate methods** (`componentDidMount`, `componentDidUpdate`, `componentWillUnmount`), while function components use **hooks** (`useEffect`), which gather all the logic in one place. **Key point:** hooks give a more flexible and universal way to control the same lifecycle moments that class methods handle.Shown above the full answer for quick recall.Answer (EN)Image## The main difference | Class components | Function components | | --- | --- | | Use **lifecycle methods** (`componentDidMount`, `componentDidUpdate`, `componentWillUnmount`, and others) | Use **hooks** (`useEffect`, `useLayoutEffect`, `useMemo`, and so on) | | React **calls** the methods itself at the right moment | Hooks give you a **more flexible** and **more universal** way to control these moments | | Logic is "scattered" across different methods | Logic is "gathered" in one place and can be extracted into custom hooks | --- ## Lifecycle of a class component ### Main stages and methods: | Stage | Method | When it fires | Hook equivalent | | --- | --- | --- | --- | | **Mounting** | `constructor()` | When the class instance is created | - | | | `componentDidMount()` | After the first render and insertion into the DOM | `useEffect(() => {...}, [])` | | **Updating** | `componentDidUpdate(prevProps, prevState)` | After `state` or `props` update | `useEffect(() => {...}, [deps])` | | **Unmounting** | `componentWillUnmount()` | Before removal from the DOM | `useEffect(() => { return () => {...} }, [])` | --- ### Example (classic) ```javascript class Timer extends React.Component { state = { seconds: 0 }; componentDidMount() { this.interval = setInterval(() => { this.setState({ seconds: this.state.seconds + 1 }); }, 1000); } componentWillUnmount() { clearInterval(this.interval); } render() { return <p>Seconds elapsed: {this.state.seconds}</p>; } } ``` --- ## Lifecycle of a function component In the "function world" there are no separate methods - everything is handled with **hooks**. The main tool is `useEffect`. ### Stage equivalents: | Stage | How it is implemented | | --- | --- | | **Mounting** | `useEffect(() => {...}, [])` | | **Updating** | `useEffect(() => {...}, [deps])` | | **Unmounting** | `useEffect(() => { return () => {...} }, [])` | --- ### Example (the hooks equivalent) ```javascript function Timer() { const [seconds, setSeconds] = useState(0); useEffect(() => { const id = setInterval(() => setSeconds(s => s + 1), 1000); return () => clearInterval(id); // cleanup - the componentWillUnmount equivalent }, []); return <p>Seconds elapsed: {seconds}</p>; } ``` --- ## Key differences in approach | # | Class component | Function component | | --- | --- | --- | | 1 | Split across methods (`componentDidMount`, `componentDidUpdate`, …) | Everything happens inside `useEffect` with dependencies | | 2 | Logic is "smeared" across different places | Logic is grouped by meaning (hooks can be extracted into custom ones) | | 3 | Has `this` and state via `this.state` / `this.setState` | Uses `useState` / `useReducer`, no `this` | | 4 | `setState` is always asynchronous and merges objects | `useState` works with any type of data, including objects and functions | | 5 | A single class instance lives the whole time | The function is called again on every render | | 6 | Hard to reuse logic (only HOC or render props) | Easy to split and reuse via **custom hooks** | | 7 | A more "imperative" style | A more "declarative" and functional style | --- ## Illustration ### The class approach: ```javascript constructor() ↓ render() ↓ componentDidMount() ↓ componentDidUpdate() ↓ componentWillUnmount() ``` ### The function approach: ```javascript Render → useEffect(() => {...}, []) Render → useEffect(() => {...}, [deps]) Unmount → cleanup() ``` --- ## Why React moved to hooks - Hooks simplify the code: less boilerplate (`this`, bind, constructor). - They let you **split logic by meaning**, not by stage. - They make logic reuse easier (via custom hooks). - They work better with TypeScript and a functional style. - They support **Concurrent Rendering** (React 18+). --- ## Summary | Aspect | Class component | Function component | | --- | --- | --- | | Lifecycle API | Methods (`componentDidMount`, `componentDidUpdate`, `componentWillUnmount`) | Hooks (`useEffect`, `useLayoutEffect`, cleanup functions) | | State | `this.state` + `this.setState()` | `useState`, `useReducer` | | Context | `contextType` | `useContext()` | | Complexity of logic | Scattered across methods | Focused in hooks | | Reuse | Via HOC/render props | Via **custom hooks** | | "this" | Present | Absent | | Performance / convenience | More cumbersome | More declarative and flexible | --- **The main idea:** > Class components manage the lifecycle through **separate methods**, > while function components do it through **hooks (**`useEffect`**)**, > which combine all the lifecycle logic in one place and make it easy to reuse.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.