Suggest an editImprove this articleRefine the answer for “Why is it important to specify all effect dependencies?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Dependencies** are all the values your effect uses inside itself (variables, props, functions, state, etc.); React re-runs the effect only when one of them changes. **Key point:** if you don't specify a dependency, React substitutes an outdated version of that variable, and the effect works with "frozen" stale data.Shown above the full answer for quick recall.Answer (EN)Image## What effect dependencies are Dependencies are **all the values your effect uses inside itself** (variables, props, functions, state, etc.). ```javascript useEffect(() => { console.log(count); // ← dependency }, [count]); ``` React will **re-run the effect only** when `count` changes. --- ## Why it's important to specify all dependencies Because React **"remembers"** the values of variables that were current at the last render. If you don't specify a dependency, React substitutes the **old ("stale") version** of that variable. --- ### Example with a bug ```javascript function Example() { const [count, setCount] = useState(0); useEffect(() => { const id = setInterval(() => { console.log(count); // always 0! setCount(count + 1); }, 1000); }, []); // ← count is not specified! return <p>{count}</p>; } ``` What happens: - `useEffect` runs once, on mount. - The closure "captures" the value `count = 0`. - Every second, `setCount(0 + 1)` gets called again and again. - But inside the effect, `count` **is never updated**, because the effect never re-runs. → The result is a **"stale closure"** and incorrect behavior. --- ### Correct: ```javascript useEffect(() => { const id = setInterval(() => { setCount(c => c + 1); // use a functional update }, 1000); return () => clearInterval(id); }, []); // no dependencies needed now ``` or, if the effect uses a dependency directly: ```javascript useEffect(() => { console.log("Count:", count); }, [count]); // dependency specified ``` --- ## What happens if a dependency is skipped | Scenario | What happens | |---|---| | Dependency not specified | The effect uses a stale value | | Dependency changes but is not specified | React does not re-run the effect → logic bug | | All dependencies specified | The effect correctly reacts to data changes | --- ## How React helps React ships with a linter: ```javascript npm install eslint-plugin-react-hooks --save-dev ``` And in `.eslintrc`: ```javascript { "plugins": ["react-hooks"], "rules": { "react-hooks/exhaustive-deps": "warn" } } ``` It will warn you if you forgot to specify something: ```javascript React Hook useEffect has a missing dependency: 'count'. Either include it or remove the dependency array. ``` --- ## Tips **Specify everything used inside the effect**, except: - constants and built-in APIs (for example, `window`, `document`), - values that are guaranteed not to change (for example, refs). If you don't want to depend on a variable, use a **functional update** (`setState(prev => ...)`). Don't be afraid of "extra" dependencies, **React guarantees optimization**. What matters most is **predictability** and the absence of hidden bugs. --- ## Summary | Question | Answer | |---|---| | Why is it important to specify all dependencies | So React knows when to update the effect and does not use stale values | | What happens if you don't specify one | The effect works with "frozen" stale data | | How to do it correctly | Specify all values used inside the effect | | How to help yourself | Use the ESLint plugin `react-hooks/exhaustive-deps` |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.