如何监听 div 是否渲染完成

读者来稿 · admin与 batype 的 AI 分身对话整理

·76 字 · 约 1 分钟#React#TypeScript

在使用 Next.js 加载 NextMarkdownPreview 时。 按需加载时,可能会出现加载较慢的现象。 此时如果通过 document 获取当前容器的内容时会出现无法获取的现象,可以通过 MutationObserverdivref 对象进行监听。 然后监听childList的变化。

'use click'
import React, { useEffect, useRef } from 'react'
import { Components } from 'react-markdown'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import {
  materialDark,
  materialLight
} from 'react-syntax-highlighter/dist/esm/styles/prism'

import { Code } from '@nextui-org/react'

import 'highlight.js/styles/github.css'
import 'katex/dist/katex.min.css'
// import 'github-markdown-css'
// import './index.css'
import { Image } from 'antd'
import HText from '../HText'
import { useTheme } from 'next-themes'
import dynamic from 'next/dynamic'

const NextMarkdownPreview = dynamic(
  () => {
    return import('react-monaco-markdown').then(res => res.NextMarkdownPreview)
  },
  {
    ssr: false
  }
)

class ReactMarkdownProps {
  code? = '' as any
  isToc? = false as boolean
  id!: string
  onCompute?: () => void
  changeLoading?: (value: boolean) => void
}
const styleMd = {
  dark: materialDark,
  light: materialLight
}

const NextMarkdown: React.FC<ReactMarkdownProps> = ({
  code,
  id,
  onCompute,
  changeLoading
}) => {
  const { theme } = useTheme()

  const divRef = useRef<any>(null)

  useEffect(() => {
    if (!divRef.current) return
    changeLoading?.(true)
    const observer = new MutationObserver(() => {
      // 当 divRef.current 下的文本内容发生变化时,这个回调会被调用
      console.log('divRef content changed:', divRef.current.textContent.length)
      onCompute?.()
      changeLoading?.(false)
    })

    // 配置观察器选项(这里根据需要配置,例如只监听childList变化)
    const config = { childList: true, subtree: true }

    // 开始观察 divRef.current
    observer.observe(divRef.current, config)

    // 清理函数,移除观察器以避免内存泄漏
    return () => {
      observer.disconnect()
    }
  }, [divRef])

  return (
    <div className="flex">
      <div id={id} className="w-[100%]" ref={divRef}>
        <NextMarkdownPreview
          theme={theme === 'dark' ? 'vs-dark' : 'vs-light'}
          code={code}
        />
      </div>
    </div>
  )
}

export default NextMarkdown

相关文章

  • react-monaco-markdown 操作手册

    react-monaco-markdown是一个React组件,集成了Monaco编辑器和Markdown解析,支持实时预览和编辑Markdown文档。支持npm、pnpm、yarn安装。提供多种配置选项,如主题、只读模式、自定义渲染等。适用于Next.js等SSR环境。MIT许可。

  • monaco-editor-react

    Monaco Editor for React集成了monaco-editor,适用于任何React应用,无需配置webpack等打包工具。支持TypeScript重写,提供多模型编辑器,与@monaco-editor/loader集成,提供开发/游乐场地。主要特性包括:无需配置即可使用、支持多模型编辑、提供Editor和DiffEditor组件、支持自定义主题和语言、提供丰富的API和事件处理。

  • 我对 React Server Components 的看法:方向对了,代价被低估了

    RSC 解决的是真问题,但它给心智模型和生态带来的撕裂,比宣传里说的大得多。