2

问题 Desp:如何在 react 项目中使用 prismjs 突出显示自定义语法?

我按照指南newlang创建了一个扩展语法文件(我们称之为)。

而且我知道在 prismjs 中有三种方法可以突出显示代码:

  • highlightElement()
  • highlightAll()
  • highlight()

首先,我尝试在我的应用程序中要求我的自定义语法文件。

import 'utils/highlight/prism-newlang';

然后,在我的高亮组件中,

  • 方法 1: highlightElement(): ❌<strong>无法突出显示我的代码
import Prism from 'prismjs';

function CodeHighlight({ value, language }) {
  const codeEle = useRef(null);

  useEffect(() => {
    Prism.highlightElement(codeEle.current, false);
  }, []);

  return (
    <pre className={`language-${language}`}>
      <code ref={codeEle} className={`language-${language}`}>
        {value}
      </code>
    </pre>
  );
}
  • 方法 2: highlightAll(): ❌<strong>无法突出显示我的代码
  • 方法 3: highlight(): ✅<strong>可以让我的代码突出显示
import { highlight, languages } from 'prismjs/components/prism-core';

function CodeHighlight({ value, language }) {
  const codeNode = useRef(null);

  useEffect(() => {
    const code = codeNode.current.textContent;
    const highlightHTML = highlightCode(code, language);
    codeNode.current.innerHTML = highlightHTML;
  });

  return (
    <pre className={`language-${language}`}>
      <code ref={codeNode} className={`language-${language}`}>
        {value}
      </code>
    </pre>
  );
}

我想知道方法1和2的问题是什么。(会是自定义语法文件的加载顺序问题吗?)

4

1 回答 1

2

对于将来遇到此问题的人,我能够使第一种方法起作用。在我的例子中,我调用Prism.highlight了在 DOM 甚至用internalText. 我现在使用在useEffect渲染 DOM 后调用的钩子,诀窍是您需要将 声明internalText为订阅参数。

我已经附加了我的 Typescript 组件。

希望这可以帮助。

import React, { useState, ChangeEvent, useRef, useEffect } from 'react'
import './prism.css'
import Prism from "prismjs";

export function CodeBlockTile() {
  const language = "javascript"

  const codeElement = useRef<HTMLElement | null>(null);
  const [internalText, setInternalText] = useState<string>("")

  const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
    setInternalText(event.target.value);
  };

  useEffect(() => {
    if (codeElement.current) {
      Prism.highlightElement(codeElement.current)
    }
  }, [internalText])


  return (
    <div>
      <textarea onChange={handleChange} value={internalText}>

      </textarea>
      <pre>
        <code ref={codeElement} className={`language-${language}`}>
          {internalText}
        </code>
      </pre>
    </div>
  )
}

于 2020-02-07T19:10:57.340 回答