Suggest an editImprove this articleRefine the answer for “useEffect and asynchronous code”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Asynchronous requests** run inside `useEffect()` because a React component must be a pure function with no side effects, and `useEffect` is the only place React allows side effects, after the render has already completed. **Key point:** `useEffect` gives control over exactly when the request runs (through the dependency array) and lets you correctly clean up the effect through a cleanup function.Shown above the full answer for quick recall.Answer (EN)Image## 1. A React component must be a **pure function** A component in React is a **pure function** that: - accepts input data (`props`); - returns a **description of the UI** (`JSX`); - **must not have side effects** (for example, network requests, timers, logs, and so on). A **pure function** is a function that, given the same inputs, **always returns the same result**, and **does not change external state**. Asynchronous requests (`fetch`, `axios`, `WebSocket`, and so on) are **side effects**, they interact with the outside world (the network, an API, disk, the browser). That is why React **forbids running side effects during render** (inside the component function's body), so as not to break the principle of predictability. --- ## 2. `useEffect()` runs **after the render** When React calls the component, it: 1. calls the function -> gets JSX (a pure result); 2. **paints** that JSX into the DOM; 3. and only then - **runs the side effects** registered through `useEffect()`. This is the ideal place for asynchronous operations because: - the UI is already mounted (you can show "Loading..."); - you can safely update state without affecting the current render. Example: ```javascript useEffect(() => { fetch('/api/user') .then(res => res.json()) .then(data => setUser(data)); }, []); ``` Here React first shows the component with `Loading...`, and after the request finishes it updates the `state` and re-renders the updated UI. --- ## 3. You cannot write asynchronous code directly in the component If you try: ```javascript function User() { const res = await fetch('/api/user'); // Error const data = await res.json(); return <div>{data.name}</div>; } ``` React **cannot await** `await` in client components (except Server Components). It expects the component to synchronously return JSX, not a promise. So this will cause an error. `useEffect()` is exactly what lets you **defer the execution** of such asynchronous operations until React finishes the render phase. --- ## 4. Controlling dependencies `useEffect` accepts a second argument - a dependency array: ```javascript useEffect(() => { fetch(`/api/users/${id}`) .then(r => r.json()) .then(setUser); }, [id]); ``` This way you can: - call the request **only once** (`[]`); - or **only when specific data changes** (`[id]`). This gives you full control over *exactly when* the request runs. Without `useEffect` you would not have this control - requests would fire on every render. --- ## 5. The ability to clean up (`cleanup`) If the component unmounts while data is loading, `useEffect` lets you **clean up the effect** so you do not update `state` on an unmounted component: ```javascript useEffect(() => { let active = true; fetch('/api/data') .then(r => r.json()) .then(data => { if (active) setData(data); }); return () => { active = false }; // cleanup }, []); ``` Without `useEffect` this would be impossible to implement correctly. --- ## 6. React 18 and asynchronous renders React 18 introduced **asynchronous rendering (Concurrent Rendering)**. With it, a render can be: - paused, - interrupted, - retried. If asynchronous requests ran during render, React would not be able to safely interrupt them - this would cause data races, leaks, and duplicate requests. `useEffect` solves this - it runs **after a successful commit phase**, that is, only when the component has actually been painted. --- ## SUMMARY | What happens | Why it matters | |---|---| | The component must be a pure function | Asynchronous operations are side effects | | `useEffect()` runs after the render | It is safe to make requests | | The second `[]` argument controls the frequency | You can avoid unnecessary requests | | The effect can be cleaned up | No leaks or data races | | Compatible with Concurrent Rendering | React can interrupt and retry renders without issues | --- ### In short: > Asynchronous requests run inside `useEffect()` > because it is the **only place** where React allows side effects, > after the render has finished, with control over dependencies and the ability to clean up.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.