fix(penpal): stabilize MarkdownViewer components to preserve mermaid SVGs#543
Merged
fix(penpal): stabilize MarkdownViewer components to preserve mermaid SVGs#543
Conversation
…SVGs The components useMemo in MarkdownViewer depended on [highlights], causing new function references on every highlight change. React-Markdown treats component functions as element types, so changed references triggered unmount/remount of all custom components — destroying externally-rendered mermaid SVGs and their highlight overlays. Fix: store highlights in a ref and read from it in the code component, allowing useMemo to use [] (no deps) for stable function references. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Commit
bb7b31bchanged thecomponentsuseMemo in MarkdownViewer fromuseMemo(…, [])touseMemo(…, [highlights])so thecodecomponent could read highlights for code block highlighting. That was the logically correct change for code highlights to work, but it had a side effect:componentsgot new function references whenever highlights changed. React-Markdown treats component functions as element types, so changed references triggered unmount/remount of all custom components — destroying externally-rendered mermaid SVGs and their highlight overlays.The bug wasn't caught because all existing MarkdownViewer tests rendered once and checked output. None exercised React's reconciliation across re-renders. A single-render test can never catch this class of bug because the first render is always correct — the destruction happens when React sees new component function references on a subsequent render and unmounts/remounts.
Fix: Store highlights in a ref (
highlightsRef) and read from it in thecodecomponent, allowinguseMemoto use[]for stable function references. React reconciles in place, preserving mermaid SVGs.Testing gap closed: Added a test that uses
rerender()and checks DOM element reference identity (toBe) on the mermaid container. If anyone changes theuseMemodeps back to[highlights](or adds any dependency that causes component function recreation), this test fails immediately — the mermaid container would be a different DOM node after re-render.🤖 Generated with Claude Code