簡體   English   中英

利用<component />帶有危險的SetInnerHTML

[英]Use <Component /> with dangerouslySetInnerHTML

首先,我確實嘗試查看一些類似的問題,但找不到與我的情況最匹配的問題,我需要多個 arguments。

我有一個包含原始 HTML 數據的變量,包括一個長段落,如果它太長我需要截斷。 為了讓生活更簡單,我使用了一個模塊來處理這個( read-more-react )。 read-more-react 需要填寫一些字段,包括文本本身,以及截斷之前的一些其他字段,例如最小和最大字符。

Gatsby 解析原始 HTML 數據的建議方法是使用dangerouslySetInnerHTML ,但我在包含我的組件時遇到了一些問題。 我嘗試使用 read-more-react 模塊而不使用dangerouslySetInnerHTML 它可以工作,但只輸出原始 HTML " <h1>A title</h1><p>Some copy...</p> etc) 而不實際解析它。

相反,我嘗試了這個;


    <div
      className="md container"
      dangerouslySetInnerHTML={{
        __html: `
          <ReadMoreReact
            text=${htmlContent}
            min="180"
            ideal="190"
            max="200"
            readMoreText="Read more"
          />
        `,
      }}
    />

但我得到一個奇怪的 output;

標題

一些副本

min="180" ideal="190" max="200" readMoreText="Read more" />

所以這顯然是行不通的。 任何人都可以提出解決方法嗎?

read-more-react似乎只處理文本,而不是 html。
您可能應該在將 html 字符串傳遞給 ReadMoreReact 組件之前對其進行解析,以便將段落與 rest 分開並提取其文本內容。
實際上,您可以使用 DOM 做到這一點:

 const htmlString = "<h1>This is the title</h1><p>The innerText property of the HTMLElement interface represents the \"rendered\" text content of a node and its descendants. As a getter, it approximates the text the user would get if they highlighted the contents of the element with the cursor and then copied it to the clipboard.</p>" const dummyElement = document.createElement('div') dummyElement.innerHTML = htmlString; const titleText = dummyElement.querySelector('h1').innerText const pText = dummyElement.querySelector('p').innerText console.log('title ==>', titleText); console.log('p ==>', pText);

問題是dangerouslySetInnerHTML需要一串正常的 HTML 元素。 相反,您試圖傳入一個無效 HTML 的 React 節點(此外ReadMoreReact返回一個字符串array ,這也是無效的)。 相反,您可以使用他們的trimText實用程序 function,它可以滿足您的期望。

這些示例使用了一些高級 ES5+ 函數:

工作示例(使用鈎子):

編輯修剪 HTML 文本

import React from "react";
import { render } from "react-dom";
import trimText from "./utils/trimText";
import "./styles.css";

const htmlText =
  "<h2 style='display:inline;'>Lorem ipsum</h2> dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";

function App() {
  const [state, setState] = React.useState({
    showOriginalHTML: false,
    originalHTML: htmlText,
    trimmedHTML: trimText(htmlText, 20, 200)[0]
  });

  const handleShowText = React.useCallback(() => {
    setState(prevState => ({
      ...prevState,
      showOriginalHTML: !prevState.showOriginalHTML
    }));
  }, [setState]);

  return (
    <div className="container">
      <div
        className="text"
        dangerouslySetInnerHTML={{
          __html: `${
            !state.showOriginalHTML ? state.trimmedHTML : state.originalHTML
          }`
        }}
      />
      <button className="read-more" onClick={handleShowText}>
        {!state.showOriginalHTML ? "read more" : "show less"}
      </button>
    </div>
  );
}

render(<App />, document.getElementById("root"));

工作示例(使用類):

編輯修剪 HTML 文本 - 類

import React from "react";
import { render } from "react-dom";
import trimText from "./utils/trimText";
import "./styles.css";

const htmlText =
  "<h2 style='display:inline;'>Lorem ipsum</h2> dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";

class App extends React.Component {
  state = {
    showOriginalHTML: false,
    originalHTML: htmlText,
    trimmedHTML: trimText(htmlText, 20, 200)[0]
  };

  handleShowText = () =>
    this.setState(prevState => ({
      showOriginalHTML: !prevState.showOriginalHTML
    }));

  render = () => {
    const { originalHTML, showOriginalHTML, trimmedHTML } = this.state;

    return (
      <div className="container">
        <div
          className="text"
          dangerouslySetInnerHTML={{
            __html: `${!showOriginalHTML ? trimmedHTML : originalHTML}`
          }}
        />
        <button className="read-more" onClick={this.handleShowText}>
          {!showOriginalHTML ? "read more" : "show less"}
        </button>
      </div>
    );
  };
}

render(<App />, document.getElementById("root"));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM