You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中解析HTML字符串并结合forwardRef调用Wiris解析函数问题

问题核心原因

  1. Wiris提供的com.wiris.js.JsPluginViewer.parseElement方法要求传入真实DOM节点,你之前的代码传入了整个ref对象,调用自然失效
  2. 父组件冗余的ref数组维护逻辑导致ref绑定异常,同时useEffect依赖项配置错误,也会导致回调逻辑不触发
  3. 全局Wiris对象的加载时机如果晚于组件渲染,没有做空判断也会导致报错

方案1:子组件内部管理ref(推荐,无特殊需求优先用这个)

直接去掉冗余的forwardRef和父组件ref数组,子组件自己维护DOM引用,逻辑更清晰。

父组件Parser代码

import WirisWrapper from './WirisWrapper';

const Parser = ({ itemsArray }) => {
    return (
        <div>
            {itemsArray.map((item, index) =>
                item.type === 'math' ? (
                    <WirisWrapper
                        key={index}
                        mString={item.html}
                    />
                ) : (
                    <div key={index} dangerouslySetInnerHTML={{ __html: item.html}}>
                    </div>
                )
            )}
        </div>
    );
};

export default Parser;

子组件WirisWrapper代码

import { useRef, useEffect } from 'react';

const WirisWrapper = ({ mString }) => {
    // 子组件内部维护DOM引用
    const wirisDomRef = useRef(null);

    useEffect(() => {
        // 兼容全局Wiris对象未加载完成的场景
        const wirisInstance = window.com?.wiris?.js?.JsPluginViewer;
        if (!wirisDomRef.current || !wirisInstance) return;

        // 赋值HTML后调用解析方法,注意这里传入的是ref.current对应的DOM节点
        wirisDomRef.current.innerHTML = mString;
        wirisInstance.parseElement(wirisDomRef.current, true, function () {});
    }, [mString]); // 仅当公式字符串变更时重新执行解析

    return <div ref={wirisDomRef}></div>;
};

export default WirisWrapper;

方案2:保留父组件ref数组的修改方式

如果你确实需要在父组件中拿到所有Wiris元素的DOM引用,按如下修改即可:

父组件Parser代码

import { useRef } from 'react';
import WirisWrapper from './WirisWrapper';

const Parser = ({ itemsArray }) => {
    // 初始化ref数组,不要每次渲染都重置
    const refs = useRef(new Array(itemsArray.length));

    return (
        <div>
            {itemsArray.map((item, index) =>
                item.type === 'math' ? (
                    <WirisWrapper
                        ref={(el) => (refs.current[index] = el)}
                        key={index}
                        mString={item.html}
                    />
                ) : (
                    <div key={index} dangerouslySetInnerHTML={{ __html: item.html}}>
                    </div>
                )
            )}
        </div>
    );
};

export default Parser;

子组件WirisWrapper代码

import { forwardRef, useRef, useEffect, useImperativeHandle } from 'react';

const WirisWrapper = forwardRef(({ mString }, parentRef) => {
    const innerRef = useRef(null);
    // 将内部DOM节点暴露给父组件的ref
    useImperativeHandle(parentRef, () => innerRef.current);

    useEffect(() => {
        const wirisInstance = window.com?.wiris?.js?.JsPluginViewer;
        if (!innerRef.current || !wirisInstance) return;

        innerRef.current.innerHTML = mString;
        wirisInstance.parseElement(innerRef.current, true, function () {});
    }, [mString]);

    return <div ref={innerRef}></div>;
});

// 配合forwardRef设置组件displayName方便调试
WirisWrapper.displayName = 'WirisWrapper';

export default WirisWrapper;

内容的提问来源于stack exchange,提问作者Er.Se

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:09:04