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

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

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

【问题讨论】:

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

标签: javascript html reactjs redux


【解决方案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 并将文件的内容加载到视图中。
    猜你喜欢
    • 2018-09-14
    • 2023-04-03
    • 2019-08-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 2021-05-26
    • 1970-01-01
    相关资源
    最近更新 更多