Skip to content

Commit 0b9ae66

Browse files
authored
Add docs for useRef no no (#6846)
1 parent 46437c2 commit 0b9ae66

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

src/content/learn/synchronizing-with-effects.md

+27
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,33 @@ Usually, the answer is to implement the cleanup function. The cleanup function
598598
599599
Most of the Effects you'll write will fit into one of the common patterns below.
600600
601+
<Pitfall>
602+
603+
#### Don't use refs to prevent Effects from firing {/*dont-use-refs-to-prevent-effects-from-firing*/}
604+
605+
A common pitfall for preventing Effects firing twice in development is to use a `ref` to prevent the Effect from running more than once. For example, you could "fix" the above bug with a `useRef`:
606+
607+
```js {1,3-4}
608+
const connectionRef = useRef(null);
609+
useEffect(() => {
610+
// 🚩 This wont fix the bug!!!
611+
if (!connectionRef.current) {
612+
connectionRef.current = createConnection();
613+
connectionRef.current.connect();
614+
}
615+
}, []);
616+
```
617+
618+
This makes it so you only see `"✅ Connecting..."` once in development, but it doesn't fix the bug.
619+
620+
When the user navigates away, the connection still isn't closed and when they navigate back, a new connection is created. As the user navigates across the app, the connections would keep piling up, the same as it would before the "fix".
621+
622+
To fix the bug, it is not enough to just make the Effect run once. The effect needs to work after re-mounting, which means the connection needs to be cleaned up like in the solution above.
623+
624+
See the examples below for how to handle common patterns.
625+
626+
</Pitfall>
627+
601628
### Controlling non-React widgets {/*controlling-non-react-widgets*/}
602629
603630
Sometimes you need to add UI widgets that aren't written to React. For example, let's say you're adding a map component to your page. It has a `setZoomLevel()` method, and you'd like to keep the zoom level in sync with a `zoomLevel` state variable in your React code. Your Effect would look similar to this:

0 commit comments

Comments
 (0)