From 2ec5611f2f245072e986e52a64ee30d4002a537c Mon Sep 17 00:00:00 2001 From: Mahi Date: Thu, 1 Oct 2026 19:11:25 +0530 Subject: [PATCH 1/2] Document side effects in lazy initialization --- .../components-and-hooks-must-be-pure.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/content/reference/rules/components-and-hooks-must-be-pure.md b/src/content/reference/rules/components-and-hooks-must-be-pure.md index 973561c2251..0a85b462d54 100644 --- a/src/content/reference/rules/components-and-hooks-must-be-pure.md +++ b/src/content/reference/rules/components-and-hooks-must-be-pure.md @@ -183,6 +183,42 @@ function ExpenseForm() { // Continue rendering... } ``` +This is fine because the mutation is local and doesn't affect other components. + +Problematic case: +```js +function SubscriptionExample(){ + let subscriptionRef = useRef(null); + // 🔴 Don't do this during render + if(subscriptionRef.current == null){ + subscriptionRef.current = store.subscribe(() => { + console.log("Store Changed") + }); + } + useEffect(() =>{ + return () =>{ + subscriptionRef.current?.unsubscribe(); + } + },[]); +} +``` +This is a problematic use of lazy initialization because it perfroms an external side effect during render. If React abandons the render, the subscription may remain active without its cleanup . + +Correct approach: +```js +function SubscriptonExample(){ + const subscriptionRef = useRef(null); + useEffect(() =>{ + subscriptionRef.current = store.subscribe(() =>{ + // .. + }) + return () =>{ + subscriptionRef.current?.unsubscribe(); + } +},[]); +} +``` +For resources that require setup and cleanup, initialize them inside an Effect. #### Changing the DOM {/*changing-the-dom*/} From 90ed8958379c8dc24ec0398ff9a59e018ecfe867 Mon Sep 17 00:00:00 2001 From: Mahi Date: Sat, 3 Oct 2026 14:57:40 +0530 Subject: [PATCH 2/2] Format subscription example --- .../rules/components-and-hooks-must-be-pure.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/content/reference/rules/components-and-hooks-must-be-pure.md b/src/content/reference/rules/components-and-hooks-must-be-pure.md index 0a85b462d54..94885ff54d5 100644 --- a/src/content/reference/rules/components-and-hooks-must-be-pure.md +++ b/src/content/reference/rules/components-and-hooks-must-be-pure.md @@ -187,16 +187,16 @@ This is fine because the mutation is local and doesn't affect other components. Problematic case: ```js -function SubscriptionExample(){ +function SubscriptionExample() { let subscriptionRef = useRef(null); // 🔴 Don't do this during render - if(subscriptionRef.current == null){ + if(subscriptionRef.current === null) { subscriptionRef.current = store.subscribe(() => { console.log("Store Changed") }); } - useEffect(() =>{ - return () =>{ + useEffect(() => { + return () => { subscriptionRef.current?.unsubscribe(); } },[]); @@ -206,13 +206,13 @@ This is a problematic use of lazy initialization because it perfroms an external Correct approach: ```js -function SubscriptonExample(){ +function SubscriptonExample() { const subscriptionRef = useRef(null); - useEffect(() =>{ - subscriptionRef.current = store.subscribe(() =>{ + useEffect(() => { + subscriptionRef.current = store.subscribe(() => { // .. }) - return () =>{ + return () => { subscriptionRef.current?.unsubscribe(); } },[]);