如何从React组件中的其他文件呈现HTML?

时间:2015-11-28 16:40:31

标签: javascript reactjs

是否可以从React组件中的其他文件呈现HTML?

我尝试了以下操作,但它不起作用:

var React = require('react');

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

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

5 个答案:

答案 0 :(得分:46)

如果您的template.html文件只是HTML而不是React组件,那么您就不能像使用JS文件那样需要它了。

但是,如果您使用的是Browserify,则会有一个名为stringify的转换,它允许您将非js文件作为字符串。添加转换后,您将能够要求HTML文件,并将它们导出为只是字符串。

一旦您需要HTML文件,您就必须使用dangerouslySetInnerHTML prop将HTML字符串注入您的组件。

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

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

这与React的很多内容相悖。将模板创建为使用JSX的React组件而不是常规HTML文件会更自然。

JSX语法使表达结构化数据(如HTML)变得非常容易,尤其是当您使用stateless function components时。

如果您的template.html文件看起来像这样

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

然后你可以把它转换成一个看起来像这样的JSX文件。

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

然后你可以在不需要stringify的情况下要求和使用它。

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

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

它维护原始文件的所有结构,但利用了React的道具模型的灵活性,并允许编译时语法检查,与常规HTML文件不同。

答案 1 :(得分:4)

您可以使用dangerouslySetInnerHTML属性注入任意HTML:

// Assume from another require()'ed module:
var html = '<h1>Hello, world!</h1>'

var MyComponent = React.createClass({
  render: function() {
    return React.createElement("h1", {dangerouslySetInnerHTML: {__html: html}})
  }
})

ReactDOM.render(React.createElement(MyComponent), document.getElementById('app'))
<script src="https://fb.me/react-0.14.3.min.js"></script>
<script src="https://fb.me/react-dom-0.14.3.min.js"></script>
<div id="app"></div>

您甚至可以对此模板行为进行组件化(未经测试):

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'/>

有了这个,template.html(在同一目录中)看起来像(再次,未经测试):

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

答案 2 :(得分:1)

通常只有从道具渲染的组件。像这样:

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

然后在您拥有逻辑的上层组件中,您只需导入模板组件并传递所需的道具。您的所有逻辑都保留在更高级别的组件中,而模板只会呈现。这是实现模板的可能方式。比如Angular。

没有办法只使用jsx的.jsx文件并在React中使用它,因为jsx不是真正的html,而是React管理的虚拟DOM的标记。

答案 3 :(得分:1)

如果模板是反应组件,你可以这样做。

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')
 );

如果您使用的是Material-UI,为兼容性而使用Material-UI Components,则不需要正常输入。

答案 4 :(得分:0)

您可以使用危险地使用SetInnerHTML来做到这一点:

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文件必须位于公共文件夹