From d8f611a3a5a488d46688fe0a728abb70ada0df48 Mon Sep 17 00:00:00 2001 From: DeveloperViraj Date: Mon, 6 Oct 2025 23:29:32 +0530 Subject: [PATCH 1/4] fix(Sandpack): prevent phantom browser history entries on scroll (#8047) --- src/components/MDX/Sandpack/Preview.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/MDX/Sandpack/Preview.tsx b/src/components/MDX/Sandpack/Preview.tsx index ead9341b6e3..2739c1e3bd7 100644 --- a/src/components/MDX/Sandpack/Preview.tsx +++ b/src/components/MDX/Sandpack/Preview.tsx @@ -97,14 +97,18 @@ export function Preview({ const sandpackIdle = sandpack.status === 'idle'; - useEffect(function createBundler() { - const iframeElement = iframeRef.current!; +useEffect(function createBundler() { + const iframeElement = iframeRef.current!; + if (!iframeElement.dataset.registered) { registerBundler(iframeElement, clientId); + iframeElement.dataset.registered = 'true'; + } + return () => { + unregisterBundler(clientId); + iframeElement.dataset.registered = ''; + }; +}, []); - return () => { - unregisterBundler(clientId); - }; - }, []); useEffect( function bundlerListener() { From 7fb86044f2394fd1a49f7456b9464d2fa54e9f12 Mon Sep 17 00:00:00 2001 From: DeveloperViraj Date: Mon, 6 Oct 2025 23:48:26 +0530 Subject: [PATCH 2/4] chore(format): run prettier to fix CI lint errors --- src/components/MDX/Sandpack/Preview.tsx | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/components/MDX/Sandpack/Preview.tsx b/src/components/MDX/Sandpack/Preview.tsx index 2739c1e3bd7..38a6fc03171 100644 --- a/src/components/MDX/Sandpack/Preview.tsx +++ b/src/components/MDX/Sandpack/Preview.tsx @@ -97,18 +97,17 @@ export function Preview({ const sandpackIdle = sandpack.status === 'idle'; -useEffect(function createBundler() { - const iframeElement = iframeRef.current!; - if (!iframeElement.dataset.registered) { - registerBundler(iframeElement, clientId); - iframeElement.dataset.registered = 'true'; - } - return () => { - unregisterBundler(clientId); - iframeElement.dataset.registered = ''; - }; -}, []); - + useEffect(function createBundler() { + const iframeElement = iframeRef.current!; + if (!iframeElement.dataset.registered) { + registerBundler(iframeElement, clientId); + iframeElement.dataset.registered = 'true'; + } + return () => { + unregisterBundler(clientId); + iframeElement.dataset.registered = ''; + }; + }, []); useEffect( function bundlerListener() { From 8d1b914909e0724aa8719c31c4e429f85f22c394 Mon Sep 17 00:00:00 2001 From: DeveloperViraj Date: Mon, 27 Oct 2025 22:35:36 +0530 Subject: [PATCH 3/4] docs(learn): make Drink example a pure function component (fixes #8100) --- src/content/learn/conditional-rendering.md | 30 ++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/content/learn/conditional-rendering.md b/src/content/learn/conditional-rendering.md index 95be5d2e018..fdb278667b0 100644 --- a/src/content/learn/conditional-rendering.md +++ b/src/content/learn/conditional-rendering.md @@ -675,26 +675,30 @@ There are multiple ways you could go about this, but here is one starting point: ```js function Drink({ name }) { - let part, caffeine, age; - if (name === 'tea') { - part = 'leaf'; - caffeine = '15–70 mg/cup'; - age = '4,000+ years'; - } else if (name === 'coffee') { - part = 'bean'; - caffeine = '80–185 mg/cup'; - age = '1,000+ years'; - } + const drinks = { + tea: { + part: 'leaf', + caffeine: '15–70 mg/cup', + age: '4,000+ years' + }, + coffee: { + part: 'bean', + caffeine: '80–185 mg/cup', + age: '1,000+ years' + } + }; + + const info = drinks[name]; return (

{name}

Part of plant
-
{part}
+
{info.part}
Caffeine content
-
{caffeine}
+
{info.caffeine}
Age
-
{age}
+
{info.age}
); From d982e32809845a5b304d033c7970e9a068ddc140 Mon Sep 17 00:00:00 2001 From: DeveloperViraj Date: Tue, 28 Oct 2025 00:02:06 +0530 Subject: [PATCH 4/4] Docs(Learn): clarify Challenge 2 explanation about getVisibleTodos() --- src/content/learn/you-might-not-need-an-effect.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/content/learn/you-might-not-need-an-effect.md b/src/content/learn/you-might-not-need-an-effect.md index 39a1dc74045..c9030a159e9 100644 --- a/src/content/learn/you-might-not-need-an-effect.md +++ b/src/content/learn/you-might-not-need-an-effect.md @@ -1272,7 +1272,9 @@ input { margin-top: 10px; } -This approach satisfies the requirements too. When you type into the input, only the `text` state variable updates. Since the `text` state variable is in the child `NewTodo` component, the parent `TodoList` component won't get re-rendered. This is why `getVisibleTodos()` doesn't get called when you type. (It would still be called if the `TodoList` re-renders for another reason.) +This approach works because `getVisibleTodos()` is only called when its dependencies (`todos` or `showActive`) change. In the original implementation, typing in the input doesn’t trigger additional calls because the `text` state is local to the `NewTodo` component and not part of the dependencies. + +The key idea is that both the initial and extracted versions avoid unnecessary recomputations—the update to `text` does not cause `getVisibleTodos()` to run. Extracting `NewTodo` mainly improves clarity by keeping the input state isolated, not by changing performance behavior.