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

如何在React与TypeScript中正确加载LaTeX自定义HTML元素?

React+TypeScript加载LaTeX内容的实现优化咨询

我是TypeScript新手,尝试在网站中加载LaTeX内容,不确定当前实现是否为最优方案,寻求专业建议。当前实现代码如下:

main.tsx

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <Latex path="/latex/latex.tex"/>
      <TextBox></TextBox>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
);

index.html

<script type="module">
        import { LaTeXJSComponent } from "https://cdn.jsdelivr.net/npm/latex.js/dist/latex.mjs"
        customElements.define("latex-js", LaTeXJSComponent)
      </script>    
      <style>
        latex-js {
          display: inline-block;
          width: 55%;
          border: 1px solid rgb(0, 0, 0);
          margin-right: 2em;
        }
      </style>    
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>

App.tsx

import * as React from 'react';
import { useEffect, useState } from 'react';
import Container from '@mui/material/Container';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import Link from '@mui/material/Link';
import TextareaAutosize from '@mui/base/TextareaAutosize';
import { styled } from "@mui/material/styles";
import Button from '@mui/material/Button';
import SendIcon from '@mui/icons-material/Send'
import { Alert } from '@mui/material';

declare global {
    namespace JSX {
      interface IntrinsicElements {
        'latex-js': any;
      }
    }
}

export function Latex({ path }: { path: string }) {    
    const [fileContent, setFileContent] = useState('');
    useEffect(() => {
      async function fetchFile() {
        try {
          const response = await fetch(path);
          const text = await response.text();
          setFileContent(text);
        } catch (error) {
          console.error('Error fetching file:', error);
        }
      }
  
      fetchFile();
    }, []);
    
    return (
        <center>
        <div>
            <latex-js>{fileContent}</latex-js>
        </div>
        </center>
    );
}

当前做法:在HTML中导入脚本并定义latex-js自定义HTML元素,在App.tsx的Latex组件中通过fetch加载.tex文件内容并注入该标签,现咨询是否存在更优的实现方案。


优化方案建议

1. 完善TypeScript类型定义

当前用any定义latex-js元素类型不够严谨,建议补充更具体的类型,获得类型提示避免误用:

declare global {
  namespace JSX {
    interface IntrinsicElements {
      'latex-js': {
        src?: string; // latex.js原生支持src属性直接加载文件
        children?: string;
        preamble?: string; // 按需添加其他支持的属性
      };
    }
  }
}

2. 简化文件加载逻辑

latex.js的自定义元素本身支持src属性,无需手动写fetch逻辑,直接传入文件路径即可:

export function Latex({ path }: { path: string }) {    
    return (
        <div style={{ textAlign: 'center' }}>
            <latex-js src={path}></latex-js>
        </div>
    );
}

这样既减少代码量,又能利用组件原生的错误处理、缓存机制,比自定义fetch更可靠。

3. 样式与组件封装优化

  • 把全局样式移到React组件内,避免样式污染:
import { styled } from "@mui/material/styles";

const StyledLatex = styled('latex-js')`
  display: inline-block;
  width: 55%;
  border: 1px solid #000;
  margin-right: 2em;
`;

export function Latex({ path }: { path: string }) {    
    return (
        <div style={{ textAlign: 'center' }}>
            <StyledLatex src={path}></StyledLatex>
        </div>
    );
}
  • 替换废弃的<center>标签,用CSS的text-align: center实现居中,符合现代HTML规范。

4. 添加加载状态与错误提示

提升用户体验,加入加载中和加载失败的状态反馈:

export function Latex({ path }: { path: string }) {    
    const [isLoading, setIsLoading] = useState(true);
    const [hasError, setHasError] = useState(false);

    const handleLoad = () => setIsLoading(false);
    const handleError = () => {
        setIsLoading(false);
        setHasError(true);
    };

    return (
        <div style={{ textAlign: 'center' }}>
            {isLoading && <Typography variant="body1">加载LaTeX内容中...</Typography>}
            {hasError && <Alert severity="error">LaTeX内容加载失败,请检查文件路径</Alert>}
            {!isLoading && !hasError && (
                <StyledLatex 
                    src={path} 
                    onLoad={handleLoad} 
                    onError={handleError}
                ></StyledLatex>
            )}
        </div>
    );
}

5. 集中管理依赖

如果项目用包管理器(npm/yarn/pnpm),可以将latex.js安装为本地依赖,替代CDN引入:

npm install latex.js

然后在组件内初始化自定义元素,让依赖管理更集中:

import { LaTeXJSComponent } from 'latex.js';
import { useEffect } from 'react';

export function Latex({ path }: { path: string }) {    
    useEffect(() => {
        if (!customElements.get('latex-js')) {
            customElements.define('latex-js', LaTeXJSComponent);
        }
    }, []);

    // ...其余代码
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:52:33