[javascript] How can I render HTML from another file in a React component?

Is it possible to render HTML from another file in a React component?

I have tried the following, but it does not work:

var React = require('react');

/* Template html */
var template = require('./template');

module.exports = React.createClass({
    render: function() {
        return(
            <template/>
        );
    }
});

This question is related to javascript reactjs

The answer is


It is common to have components that are only rendering from props. Like this:

class Template extends React.Component{
  render (){
    return <div>this.props.something</div>
  }
}

Then in your upper level component where you have the logic you just import the Template component and pass the needed props. All your logic stays in the higher level component, and the Template only renders. This is a possible way to achieve 'templates' like in Angular.

There is no way to have .jsx file with jsx only and use it in React because jsx is not really html but markup for a virtual DOM, which React manages.


You can use the dangerouslySetInnerHTML property to inject arbitrary HTML:

_x000D_
_x000D_
// Assume from another require()'ed module:_x000D_
var html = '<h1>Hello, world!</h1>'_x000D_
_x000D_
var MyComponent = React.createClass({_x000D_
  render: function() {_x000D_
    return React.createElement("h1", {dangerouslySetInnerHTML: {__html: html}})_x000D_
  }_x000D_
})_x000D_
_x000D_
ReactDOM.render(React.createElement(MyComponent), document.getElementById('app'))
_x000D_
<script src="https://fb.me/react-0.14.3.min.js"></script>_x000D_
<script src="https://fb.me/react-dom-0.14.3.min.js"></script>_x000D_
<div id="app"></div>
_x000D_
_x000D_
_x000D_

You could even componentize this template behavior (untested):

class TemplateComponent extends React.Component {
  constructor(props) {
    super(props)
    this.html = require(props.template)
  }

  render() {
    return <div dangerouslySetInnerHTML={{__html: this.html}}/>
  }

}

TemplateComponent.propTypes = {
  template: React.PropTypes.string.isRequired
}

// use like
<TemplateComponent template='./template.html'/>

And with this, template.html (in the same directory) looks something like (again, untested):

// ./template.html
module.exports = '<h1>Hello, world!</h1>'

If your template.html file is just HTML and not a React component, then you can't require it in the same way you would do with a JS file.

However, if you are using Browserify — there is a transform called stringify which will allow you to require non-js files as strings. Once you have added the transform, you will be able to require HTML files and they will export as though they were just strings.

Once you have required the HTML file, you'll have to inject the HTML string into your component, using the dangerouslySetInnerHTML prop.

var __html = require('./template.html');
var template = { __html: __html };

React.module.exports = React.createClass({
  render: function() {
    return(
      <div dangerouslySetInnerHTML={template} />
    );
  }
});

This goes against a lot of what React is about though. It would be more natural to create your templates as React components with JSX, rather than as regular HTML files.

The JSX syntax makes it trivially easy to express structured data, like HTML, especially when you use stateless function components.

If your template.html file looked something like this

<div class='foo'>
  <h1>Hello</h1>
  <p>Some paragraph text</p>
  <button>Click</button>
</div>

Then you could convert it instead to a JSX file that looked like this.

module.exports = function(props) {
  return (
    <div className='foo'>
      <h1>Hello</h1>
      <p>Some paragraph text</p>
      <button>Click</button>
    </div>
  );
};

Then you can require and use it without needing stringify.

var Template = require('./template');

module.exports = React.createClass({
  render: function() {
    var bar = 'baz';
    return(
      <Template foo={bar}/>
    );
  }
});

It maintains all of the structure of the original file, but leverages the flexibility of React's props model and allows for compile time syntax checking, unlike a regular HTML file.


You could do it if template is a react component.

Template.js

var React = require('react');

var Template = React.createClass({
    render: function(){
        return (<div>Mi HTML</div>);
    }
});

module.exports = Template;

MainComponent.js

var React = require('react');
var ReactDOM = require('react-dom');
var injectTapEventPlugin = require("react-tap-event-plugin");
var Template = require('./Template');

//Needed for React Developer Tools
window.React = React;

//Needed for onTouchTap
//Can go away when react 1.0 release
//Check this repo:
//https://github.com/zilverline/react-tap-event-plugin
injectTapEventPlugin();

var MainComponent = React.createClass({
    render: function() {
        return(
            <Template/>
        );
    }
});

// Render the main app react component into the app div.
// For more details see: https://facebook.github.io/react/docs/top-level-api.html#react.render
ReactDOM.render(
  <MainComponent />,
  document.getElementById('app')
 );

And if you are using Material-UI, for compatibility use Material-UI Components, no normal inputs.


You can use dangerouslySetInnerHTML to do this:

import React from 'react';
function iframe() {
    return {
        __html: '<iframe src="./Folder/File.html" width="540" height="450"></iframe>'
    }
}


export default function Exercises() {
    return (
        <div>
            <div dangerouslySetInnerHTML={iframe()} />
        </div>)
}

HTML files must be in the public folder