react-streamdown: 当组件发生变化而没有新文本时,代码块会保留之前的高亮器

作者: okisdev创建于 2026年9月17日更新于 2026年9月17日
标签bug

更改 components.SyntaxHighlightercomponents.CodeHeadercomponentsByLanguage 的某个项在 StreamdownTextPrimitive 中不会更新已经渲染的代码块,直到其文本发生变化。在 f36e9450069c3d0f17(之前 #7651)上,在流式和静态模式下重现此问题:

typescript
const view = (SyntaxHighlighter: ComponentType<SyntaxHighlighterProps>) => (
  <TextMessagePartProvider text={"```ts\nconst x = 1;\n```"} isRunning={false}>
    <StreamdownTextPrimitive
      mode="static"
      componentsByLanguage={{ ts: { SyntaxHighlighter } }}
    />
  </TextMessagePartProvider>
);
const { rerender } = render(view(First));
rerender(view(Second));
// First 仍然被渲染,而 Second 从未被渲染

useAdaptedComponents 将一个 code 组件作为一个稳定的 useCallbackRef 包装器流式传递给 streamdown (#7082),而 StreamdownTextPrimitive 会稳定地映射组件,因此 streamdown 会接收相同的属性。streamdown 2.6.0 的 Streamdown 备忘录不会比较 components,而其 Block 备忘录会通过标识比较条目,因此不会重新渲染;新的适配器只会在下次该块重新渲染时触及该块,例如新文本或 animated 消息完成。

内容来源: assistant-ui/assistant-ui