React:如何加载和渲染外部 html 文件?

Posted

技术标签:

【中文标题】React:如何加载和渲染外部 html 文件?【英文标题】:React: how to load and render external html file? 【发布时间】:2017-02-27 18:18:27 【问题描述】:

我使用 React 和 Redux 构建了一个小型博客应用程序。 博客显示帖子页面,其中包含帖子的标题、作者、标签和描述。单击标题或“阅读更多”按钮时,我想从本地项目的数据文件夹中加载并呈现一个带有相应帖子的 html 文件,其中包含所有帖子。

Redux 正在管理博客的状态,加载包含 8 个不同帖子的初始 posts.json 文件,包括数据文件夹中相应 html 文件的 htmlPath。

【问题讨论】:

你想呈现外部 html 静态和“原样”,还是需要以某种方式“解析”它或以某种方式使其与 React(例如组件状态)交互? 只是渲染它,假设我点击帖子的标题“Hello World”并从文件 hello-world.html 中获取所有渲染的帖子 人们会在这个问题上拉扯他们的头发。听起来不对。然而,一个人开始用 React 构建应用程序,期待奇迹,然后到一个地步,想要用 php 做一件容易、简单、明确、直接的事情。 【参考方案1】:

虽然 Chris 的回答很好,但需要进行更多的挖掘才能使其发挥作用。以下是您需要采取的步骤:

将 html 加载器添加到您的项目中:

npm i -D html-loader

将以下规则添加到您的 webpack.config 文件中:


  test: /\.(html)$/,
  use: 
    loader: 'html-loader',
    options: 
      attrs: [':data-src']
    
  

现在您可以按如下方式导入您的 html 文件:

import React,  Component  from 'react';
import Page from './test.html';
var htmlDoc = __html: Page;

export default class Doc extends Component 
  constructor(props)
    super(props);
  

  render()
     return (<div dangerouslySetInnerHTML=htmlDoc />)

【讨论】:

我完全按照你的描述做了,但是我得到了一个页面的字符串,比如“samples/myHtmlCode.html” 哦,等等...我也将 .html 文件用于其他加载程序的测试。现在可以了 这对于从服务器获取 html 不起作用,它只会使用 html 源作为数据 url 构建您的 webpack 项目(谁愿意这样做?) @r3wt 一年后我再次来到这里,完全按照我在上面所反对的...【参考方案2】:

你可以试试react-templates。这是“最好的”。你可以将你的模板作为一个外部文件,并且可以在你想要的时候加载它,它会像所有可用的 React API 一样呈现出来。

希望对你有帮助。

【讨论】:

【参考方案3】:

我的看法是,您需要在这里解决 2 个问题。首先是如何在 React 中设置元素的innerHTML。另一个是如何根据给定的变量(例如当前路由、文本字段的输入等)获取要呈现的特定 HTML。

1。设置元素的innerHTML

您可以使用 dangerouslySetInnerHTML 属性来做到这一点。顾名思义,它将所述元素的innerHTML 设置为您指定的任何内容...是的,“危险”是准确的,因为它旨在让您在使用此功能之前三思而后行。

Official Documentation 内容如下:

innerHTML 使用不当可能会使您面临跨站点脚本 (XSS) 攻击。众所周知,清理用户输入以进行显示很容易出错,而未能正确清理是互联网上网络漏洞的主要原因之一。

查看Demo 或下面的 sn-p。

var Demo = React.createClass(

  getInitialState: function() 
    return showExternalHTML: false;
  ,
  
  render: function() 
    return (
      <div>
        <button onClick=this.toggleExternalHTML>Toggle Html</button>
        this.state.showExternalHTML ? <div>
          <div dangerouslySetInnerHTML=this.createMarkup() ></div>
        </div> : null
      </div>
    );
  ,
  
  toggleExternalHTML: function() 
    this.setState(showExternalHTML: !this.state.showExternalHTML);
  ,
  
  createMarkup: function()  
    return __html: '<div class="ext">Hello!</div>';
  

);

ReactDOM.render(
  <Demo />,
  document.getElementById('container')
);
.ext 
  margin-top: 20px;
  width: 100%;
  height: 100px;
  background: green;
  color: white;
  font-size: 40px;
  text-align: center;
  line-height: 100px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

2。从外部源获取 HTML

请注意,上面的示例实际上并没有从外部文件中获取 HTML,而是直接作为字符串输入的。

动态获取特定文件的一种简单方法是让您的后端(例如 php)从本地文件夹中读取文件,解析文本,然后通过 AJAX 请求将其发回。

示例

//Your React component
fetchExternalHTML: function(fileName) 
  Ajax.getJSON('/myAPI/getExternalHTML/' + fileName).then(
    response => 
      this.setState(
        extHTML: response
      );
    , err => 
      //handle your error here
    
  );

【讨论】:

加载外部 HTML 是否有安全且推荐的替代方法? @colecmc,不确定你的意思。你想达到什么目的? 所以我有一些 html 作为字符串,通过 fetch 调用检索。对于 vanillaJS,我会使用 innerHTMLinsertAdjacentHTML(),但对于 React,我不确定最好的方法。我正在考虑将字符串转换为 JSON,然后通过循环 JSON 来添加组件。 @colecmc,你试过上面的方法1了吗? 我需要调整我的设置以使其正常工作,但我会试一试。感谢一百万@Chris【参考方案4】:

如果你真的确定,用服务器代码从文件系统中获取你喜欢的帖子内容到前端,并在 React 组件中显示它dangerouslySetInnerHTML

function createMarkup()  
    return __html: 'First &middot; Second'; 
;

<div dangerouslySetInnerHTML=createMarkup() />

更多文档:https://facebook.github.io/react/tips/dangerously-set-inner-html.html

【讨论】:

我知道 dangerouslySet,我无法完成的事情是当点击链接时,如何使用我在存储中的路径 ../../data/posts/html/[name]。 html 并将文件的内容加载到视图中。

以上是关于React:如何加载和渲染外部 html 文件?的主要内容,如果未能解决你的问题,请参考以下文章

create-react-app:如何在 React 渲染之前加载 html

如何加载新版本react addon

浏览器是如何渲染页面的?

浏览器是如何渲染页面的?

浏览器渲染 理解终结篇

react服务端渲染框架