React: how to load and render external html file?

后端 未结 4 466
后悔当初
后悔当初 2020-11-30 01:45

I building a small blog app using React and Redux. The blog show Posts page with title, author, tags and description of a post. When clicking on title or \"read more\" butt

相关标签:
4条回答
  • 2020-11-30 02:30

    The way I see it is that you have 2 problems to solve here. The first is how to set the innerHTML of an element in React. The other is how to get a specific HTML to render depending on a given variable (e.g the current route, the input of a textfield, etc).

    1. Setting the innerHTML of an element

    You can do this with the dangerouslySetInnerHTML prop. As the name suggests it sets the innerHTML of the said element to whatever you specify... and yes, the "dangerously" is accurate as it's intended to make you think twice before using this feature.

    The Official Documentation reads as follows:

    Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack. Sanitizing user input for display is notoriously error-prone, and failure to properly sanitize is one of the leading causes of web vulnerabilities on the internet.

    Check out this Demo or the snippet below.

    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. Fetching the HTML from an external source

    Note that the above example does not actually get the HTML from an external file, but is entered directly as a string.

    One simple way to do dynamically fetch a choose a specific file would be to let your backend (e.g php) read the file from a local folder, parse the text, and send it back through an AJAX request.

    Example

    //Your React component
    fetchExternalHTML: function(fileName) {
      Ajax.getJSON('/myAPI/getExternalHTML/' + fileName).then(
        response => {
          this.setState({
            extHTML: response
          });
        }, err => {
          //handle your error here
        }
      );
    }
    
    0 讨论(0)
  • 2020-11-30 02:36

    If you really sure, get the post contents to frontend how you like from file system with server code, and show it in React component with dangerouslySetInnerHTML:

    function createMarkup() { 
        return {__html: 'First &middot; Second'}; 
    };
    
    <div dangerouslySetInnerHTML={createMarkup()} />
    

    More in docs: https://facebook.github.io/react/tips/dangerously-set-inner-html.html

    0 讨论(0)
  • 2020-11-30 02:37

    You can try react-templates. This is 'the' best available. You can have your template as an external file and can load it whenever you want and it'll render like charm with all the React API available.

    Hope it helps.

    0 讨论(0)
  • 2020-11-30 02:41

    While Chris's answer was good, some more digging was required to make it work. Here are the steps that you need to take:

    Add html loader to your project:

    npm i -D html-loader
    

    Add the following rule to your webpack.config file:

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

    Now you can import your html file as follow:

    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} />)
    }}
    
    0 讨论(0)
提交回复
热议问题