Skip to content

Commit a80e73d

Browse files
Refine non-primitive dependency warning
1 parent ce138d0 commit a80e73d

File tree

1 file changed

+9
-51
lines changed

1 file changed

+9
-51
lines changed

src/content/reference/react/useEffect.md

Lines changed: 9 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,65 +1416,23 @@ button { margin-left: 5px; }
14161416
14171417
</Recipes>
14181418
1419-
---
1420-
1421-
### Behavior of `useEffect()` with non-primitive dependencies {/*behavior-of-useeffect-with-non-primitive-dependencies*/}
1422-
1423-
**Objects and arrays are non-primitive values**. In JavaScript, _a new object or array_ is created on every render when it is **defined inside the component body**, even if its contents are the same.
1419+
<Note>
14241420
1425-
Since `useEffect()` performs a _shallow comparison_ on its dependencies, it sees the new reference on every render and re-runs the effect. This often leads to _unnecessary work_ or even _infinite loops_.
1421+
**Avoid placing objects or arrays**, defined inside the component directly into the dependency array. Because _non-primitive values_ receive a new reference on every render, this will cause your Effect to re-run unnecessarily, leading to _performance issues or infinite loops._
14261422
1427-
For example, defining an object inline and using it as a dependency will cause the effect to run on every render
1423+
```js {4}
14281424

1429-
```js {2-5, 8}
1430-
function getData({ roomId }) {
1431-
const config = {
1432-
roomId: roomId,
1433-
limit: 10
1434-
};
1435-
useEffect(() => {
1436-
api.fetchData(config); // This fetches data for API on every render
1437-
}, [config]); // ❌ Dependency changes on every render
1438-
// ...
1425+
function ChatRoom() {
1426+
useEffect(()=>{
1427+
// ...
1428+
}, [{ limit: 10 }])
14391429
}
1440-
```
1441-
To avoid this, there are two common strategies:
14421430

1443-
1) __By using `useMemo` hook to memoize the objects and arrays:__
1444-
1445-
```js {2-5,8}
1446-
function getData({ roomId }) {
1447-
const config = useMemo(() => ({
1448-
roomId: roomId,
1449-
limit: 10
1450-
}), [roomId]);
1451-
useEffect(() => {
1452-
api.fetchData(config); // The API request will only run when 'config' changes
1453-
}, [config]);
1454-
// ...
1455-
}
14561431
```
1457-
This prevents unnecessary effect executions while still recreating the object when its relevant values change.
1458-
1459-
2) __If an object does not depend on props or state__, define it outside the component so it has a stable reference:
14601432
1461-
```js {1-4.10}
1462-
const DEFAULT_CONFIG = {
1463-
limit: 10
1464-
};
1465-
1466-
function getData() {
1467-
1468-
useEffect(() => {
1469-
api.fetchData(DEFAULT_CONFIG);// This only fetches data once on mount
1433+
To use the non-primitives values in the dependency array try using `useMemo()` hook or moving them outside the component, see the section on **[Removing unnecessary object dependencies.](/reference/react/useEffect#removing-unnecessary-object-dependencies)**.
14701434
1471-
}, [DEFAULT_CONFIG]);
1472-
// ...
1473-
}
1474-
```
1475-
_Because objects and arrays receive a new reference on each render,_ using them directly as dependencies will cause `useEffect()` to re-run unnecessarily. To avoid this use the `useMemo` Hook to memoize the value or only if the object/array does not depend on props or state define constant object/array _outside the component scope_, This ensures stable references and prevents unintentional re-renders or effect loops.
1476-
1477-
__Because objects and arrays receive a new reference on each render__, using them directly as dependencies will cause `useEffect()` to re-run unnecessarily. To avoid this, define constant objects or arrays _outside the component_, or use `useMemo()` hook to memoize values that depend on _props or state_. This ensures stable references and prevents unintentional re-renders or effect loops.
1435+
</Note>
14781436
14791437
---
14801438

0 commit comments

Comments
 (0)