web-dev-qa-db-fra.com

Comment puis-je rendre HTML à partir d'un autre fichier dans un composant React?

Est-il possible de rendre HTML à partir d'un autre fichier dans un composant React?

J'ai essayé ce qui suit, mais ça ne marche pas:

var React = require('react');

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

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

Si votre template.html Le fichier _ est uniquement du code HTML et non un composant React, vous ne pouvez donc pas l'exiger de la même façon que vous le feriez avec un fichier JS.

Cependant, si vous utilisez Browserify, il existe une transformation appelée stringify qui vous permettra d'exiger des fichiers non-js en tant que chaînes. Une fois que vous avez ajouté la transformation, vous pourrez demander des fichiers HTML et les exporter comme s'il s'agissait de chaînes.

Une fois que vous avez besoin du fichier HTML, vous devez injecter la chaîne HTML dans votre composant à l’aide de dangerouslySetInnerHTML prop .

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

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

Cela va à l’encontre de beaucoup de ce que React est sur. Cependant, il serait plus naturel de créer vos modèles en tant que React composants avec JSX, plutôt que comme HTML normal des dossiers.

La syntaxe JSX facilite l’expression de données structurées, telles que HTML, en particulier lorsque vous utilisez composants de fonction sans état .

Si votre template.html fichier ressemblait à quelque chose comme ça

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

Ensuite, vous pourriez le convertir à la place en un fichier JSX ressemblant à ceci.

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

Ensuite, vous pouvez exiger et l'utiliser sans avoir besoin de stringify.

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

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

Il conserve toute la structure du fichier d'origine, mais exploite la flexibilité du modèle d'accessoires de React et permet la vérification de la syntaxe de compilation, contrairement à un fichier HTML classique.

50
Dan Prince

Vous pouvez utiliser la propriété dangerouslySetInnerHTML pour injecter du code HTML arbitraire:

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

Vous pouvez même composant ce comportement de template (non testé):

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

Et avec ça, template.html (dans le même répertoire) ressemble à quelque chose comme (encore une fois, non testé):

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

Vous pouvez le faire si template est un composant de réaction.

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

Et si vous utilisez Material-UI, pour des raisons de compatibilité, utilisez les composants Material-UI, pas d'entrées normales.

1
Allan

Il est courant d'avoir des composants qui ne font que restituer des accessoires. Comme ça:

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

Ensuite, dans votre composant de niveau supérieur où vous avez la logique, importez simplement le composant Template et transmettez les accessoires nécessaires. Toute votre logique reste dans le composant de niveau supérieur et le modèle ne restitue que. C'est un moyen possible de réaliser des "modèles" comme dans Angular.

Il n’ya aucun moyen d’avoir un fichier .jsx uniquement avec jsx et de l’utiliser dans React car jsx n’est pas vraiment html mais un balisage pour un DOM virtuel, ce qui React gère.

1
Ivan