You need to enable JavaScript to run this app. React中@toast-ui/react-editor Viewer如何传异步initialValue
优惠活动
大模型
产品
解决方案
定价
更多

React中@toast-ui/react-editor Viewer如何传异步initialValue

核心问题原因

@toast-ui/react-editor 导出的 Viewer 组件,其 initialValue 是仅在首次挂载时生效的初始化配置,后续即使传入组件的 initialValue prop 发生变化,已经生成的Viewer实例不会自动同步更新内容。
当前代码的执行时序刚好触发了这个特性:

  • 组件首次渲染时,异步课程详情接口还未返回结果,此时Classs.content为undefined,Viewer已经带着空的初始值完成挂载
  • 接口返回后,setClasss更新状态,哪怕传给Viewer的initialValue已经是有效内容,已经挂载完成的Viewer不会响应这个prop变化,最终表现为内容不渲染
  • 页面上的隐藏textarea是原生受控组件,会直接跟随状态值更新,所以能正常读到有效内容,和Viewer的表现形成明显反差
可落地的解决方案

方案1:待异步数据就绪后再挂载Viewer组件(最推荐)

从挂载时机上避免空值初始化的问题,等Classs.content拿到有效值后再渲染Viewer组件,初始化时就能传入正确的内容,完全匹配组件的设计逻辑。
修改后的核心代码如下:

// 移除提前定义asdasd变量的逻辑,在页面渲染逻辑中加状态判断
return (
  <div style={{ width: '100%', padding: '3rem 4rem' }}>
    <div>
      {/* 隐藏的测试textarea可保留用于调试 */}
      <textarea value={Classs.content} readOnly style={{ display: "none" }}></textarea>
      <div>
        {/* 仅当content有有效值时才渲染Viewer */}
        {Classs.content ? (
          <Viewer
            ref={editorRef}
            height="500px"
            initialValue={Classs.content}
          />
        ) : (
          <div style={{ height: "500px", display: "flex", alignItems: "center", justifyContent: "center", color: "#999" }}>
            内容加载中...
          </div>
        )}
      </div>
      <Row gutter={[16, 16]}>
        <Col lg={18} sm={24}></Col>
        <Col lg={6} sm={24}>
          <ProductInfo detail={Classs} />
        </Col>
      </Row>
    </div>
  </div>
)

冗余代码修正

原代码中给Viewer传入的viewer="true"属性属于多余配置:当前导入的是只读的Viewer组件本身,不需要额外通过该属性开启只读模式,冗余传参可能触发组件prop校验警告,直接删除即可。

方案2:通过ref手动同步内容(需提前挂载场景)

如果业务要求必须在数据未返回时就完成Viewer组件挂载,可以通过ref绑定组件实例,在异步数据拿到后手动调用实例方法更新内容。
核心修改逻辑:

  • 给Viewer组件绑定已经定义好的editorRef
  • 在接口返回数据的回调中,拿到Viewer实例后调用setMarkdown方法写入内容
    对应代码片段:
useEffect(() => {
  dispatch(videoclassdetail(classId))
    .then((res) => {
      const courseData = res.payload
      setClasss(courseData)
      // 数据存在时,通过ref拿到实例手动更新内容
      if (courseData?.content && editorRef.current) {
        const viewerInstance = editorRef.current.getInstance()
        viewerInstance.setMarkdown(courseData.content)
      }
    })
}, [dispatch, classId])

注意事项

  • 调用getInstance()前必须判断ref是否已经绑定完成,避免组件未挂载时触发空指针报错
  • 不要在组件首次渲染的同步逻辑中直接调用实例方法,此时ref还未完成绑定

内容的提问来源于stack exchange,提问作者nojeong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 22:45:02