From 0b9ae66066cccce35832c35097d6cafacd99c098 Mon Sep 17 00:00:00 2001 From: Ricky Date: Thu, 9 May 2024 10:43:42 -0400 Subject: [PATCH 1/2] Add docs for useRef no no (#6846) --- .../learn/synchronizing-with-effects.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/content/learn/synchronizing-with-effects.md b/src/content/learn/synchronizing-with-effects.md index f1aa984384..4218171d4e 100644 --- a/src/content/learn/synchronizing-with-effects.md +++ b/src/content/learn/synchronizing-with-effects.md @@ -598,6 +598,33 @@ Usually, the answer is to implement the cleanup function. The cleanup function Most of the Effects you'll write will fit into one of the common patterns below. + + +#### Don't use refs to prevent Effects from firing {/*dont-use-refs-to-prevent-effects-from-firing*/} + +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`: + +```js {1,3-4} + const connectionRef = useRef(null); + useEffect(() => { + // 🚩 This wont fix the bug!!! + if (!connectionRef.current) { + connectionRef.current = createConnection(); + connectionRef.current.connect(); + } + }, []); +``` + +This makes it so you only see `"✅ Connecting..."` once in development, but it doesn't fix the bug. + +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". + +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. + +See the examples below for how to handle common patterns. + + + ### Controlling non-React widgets {/*controlling-non-react-widgets*/} 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: From 7f9a6655230555f764909240618847733ffba799 Mon Sep 17 00:00:00 2001 From: Xavi Lee Date: Fri, 10 May 2024 07:13:01 +0800 Subject: [PATCH 2/2] fix conflict --- src/content/learn/synchronizing-with-effects.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/content/learn/synchronizing-with-effects.md b/src/content/learn/synchronizing-with-effects.md index 2d6a3cd92a..3f19a82233 100644 --- a/src/content/learn/synchronizing-with-effects.md +++ b/src/content/learn/synchronizing-with-effects.md @@ -598,9 +598,6 @@ input { display: block; margin-bottom: 20px; } 下面提供一些常用的 Effect 应用模式。 -<<<<<<< HEAD -### 控制非 React 组件 {/*controlling-non-react-widgets*/} -======= #### Don't use refs to prevent Effects from firing {/*dont-use-refs-to-prevent-effects-from-firing*/} @@ -628,8 +625,7 @@ See the examples below for how to handle common patterns. -### Controlling non-React widgets {/*controlling-non-react-widgets*/} ->>>>>>> 0b9ae66066cccce35832c35097d6cafacd99c098 +### 控制非 React 组件 {/*controlling-non-react-widgets*/} 有时需要添加不是使用 React 编写的 UI 小部件。例如,假设你要向页面添加地图组件,并且它有一个 `setZoomLevel()` 方法,你希望调整缩放级别(zoom level)并与 React 代码中的 `zoomLevel` state 变量保持同步。Effect 看起来应该与下面类似: