Syntax Processing
Streaming syntax processing mechanism is designed for real-time rendering scenarios, capable of intelligently handling incomplete Markdown syntax structures to avoid rendering anomalies caused by syntax fragments.
During streaming transmission, Markdown syntax may be in an incomplete state:
// Incomplete link during transmission Click to visit [example website](https://example // Incomplete image syntax  => {return (<XMarkdowncontent="# Streaming Rendering Example\n\nVisit [Ant Design](https://ant.design) for design resources.\n\n"streaming={{hasNextChunk: true,incompleteMarkdownComponentMap: {link: 'custom-link-loading',image: 'custom-image-loading',},}}/>);};
Streaming syntax processing supports integrity checks for the following Markdown syntax:
Syntax Type | Format Example | Processing Mechanism |
---|---|---|
Links | [text](url) | Detects unclosed link markers like [text]( |
Images |  | Detects unclosed image markers like  => <span className="loading-link">🔗 Loading...</span>,ImageLoading: () => <div className="loading-image">🖼️ Image loading...</div>,};const App = () => {return (<XMarkdowncontent="Visit [Ant Design](https://ant.design) to view documentation"streaming={{hasNextChunk: true,incompleteMarkdownComponentMap: {link: 'link-loading',image: 'image-loading',},}}components={{'link-loading': CustomLoadingComponents.LinkLoading,'image-loading': CustomLoadingComponents.ImageLoading,}}/>);};
When input content changes fundamentally (non-incremental update), the component automatically resets the parsing state:
// Old content: "Hello "// New content: "Hi there!" - triggers state reset// New content: "Hello world!" - continues incremental parsing
hasNextChunk
should not always be true
, otherwise it will cause:
import { useState, useEffect } from 'react';import { XMarkdown } from '@ant-design/x-markdown';const StreamingExample = () => {const [content, setContent] = useState('');const [hasNextChunk, setHasNextChunk] = useState(true);useEffect(() => {// Simulate streaming dataconst chunks = ['# Welcome to Streaming Rendering','\n\nThis is a demonstration',' showing how to handle','[incomplete links](https://example','.com) and images','','\n\nContent completed!',];let currentIndex = 0;const interval = setInterval(() => {if (currentIndex < chunks.length) {setContent((prev) => prev + chunks[currentIndex]);currentIndex++;// Set to false on last chunkif (currentIndex === chunks.length) {setHasNextChunk(false);}} else {clearInterval(interval);}}, 500);return () => clearInterval(interval);}, []);return (<XMarkdowncontent={content}streaming={{hasNextChunk,incompleteMarkdownComponentMap: {link: 'loading-link',image: 'loading-image',},}}/>);};