Markdown Content Not Dynamically Rendering in Real-Time with React-Markdown and Socket.io

38 views Asked by At

I am developing a chat application using React, where messages, including Markdown formatted text, are sent and received in real-time using socket.io. The application utilizes a CustomMarkDown component to render the Markdown content. This component uses react-markdown for parsing Markdown content, along with rehype-raw, rehype-katex, remark-math, and remark-gfm for extended Markdown features. Additionally, react-syntax-highlighter is used for syntax highlighting within code blocks.

The CustomMarkDown component is expected to render various Markdown elements dynamically (e.g., tables, lists, and handling new lines) as they are received from the server via socket.io messages. However, I am encountering an issue where Markdown content isn't parsed and displayed correctly in real-time. Specifically, tables and lists formatted in Markdown are not rendered as expected on message receipt. Instead, they appear correctly only after refreshing the page or navigating away and then back to the chat view.

Below is the code for the CustomMarkDown component:

import { useEffect, useState } from 'react';
import Markdown from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs';
import rehypeRaw from "rehype-raw";
import rehypeKatex from 'rehype-katex';
import remarkMath from 'remark-math'
import remarkGfm from 'remark-gfm';
import 'katex/dist/katex.min.css' // `rehype-katex` does not import the CSS for you
import './CustomMarkDown.css';
import Iconify from '../Iconify';


export default function CustomMarkDown({ content }) {
 
    const Pre = ({ children }) => {
        return <>
            <pre className="blog-pre">
                <CodeCopyBtn>{children}</CodeCopyBtn>
                {children}
            </pre>
        </>
    }

 
    return (
        <>
            <Markdown
                className={'reactMarkDown'}
                remarkPlugins={[remarkMath, remarkGfm]}
                rehypePlugins={[rehypeKatex, rehypeRaw]}
                children={content}
                components={{
                    pre: Pre,
                    code(props) {
                        const { children, className, node, ...rest } = props;
                        console.log('code props', props);
                        const match = /language-(\w+)/.exec(className || '');
                        return (
                            <SyntaxHighlighter
                                {...rest}
                                children={String(children).replace(/\n$/, '')}
                                style={dark}
                                language={match ? match[1] : 'bash'}
                                PreTag="div"
                            />
                        )
                    },
                    table: ({ node, ...props }) => <table className="myCustomTableClass" {...props} />,
                    th: ({ node, ...props }) => <th className="myCustomTableHeaderClass" {...props} />,
                    td: ({ node, ...props }) => <td className="myCustomTableCellClass" {...props} />,
                }}
            />
        </>
    )
}

The issue seems related to how the component's state updates in response to new socket.io messages and how the Markdown content is processed and rendered by react-markdown.

I have verified that the Markdown syntax for the content being sent is correct. I am looking for insights into why these Markdown elements are not rendering dynamically as expected and how I can ensure that they are rendered in real-time without requiring a page refresh.

Has anyone encountered a similar issue or can provide guidance on how to troubleshoot and resolve this problem?

0

There are 0 answers