web-dev-qa-db-fra.com

React: comment charger et afficher un fichier HTML externe?

Je construis une petite application de blog en utilisant React et Redux. La page de publication du blog avec le titre, l'auteur, les balises et la description d'un message. Lorsque je clique sur le titre ou sur le bouton "En savoir plus", je souhaite charger et restituer un fichier HTML avec l'article correspondant du dossier de données d'un projet local contenant tous les articles.

Redux gère l’état du blog en chargeant le fichier initial posts.json avec 8 articles différents, y compris htmlPath pour le fichier html correspondant dans le dossier de données.

15
Intermundos

Je pense que vous avez 2 problèmes à résoudre ici. La première consiste à définir la innerHTML d'un élément dans React. L'autre consiste à obtenir un rendu HTML spécifique en fonction d'une variable donnée (par exemple, la route en cours, l'entrée d'un champ de texte, etc.).

1. Définir la innerHTML d'un élément

Vous pouvez le faire avec le prop dangerouslySetInnerHTML. Comme son nom l'indique, il définit la innerHTML de cet élément en fonction de ce que vous spécifiez ... et oui, le terme "dangereusement" est exact, car il a pour but de vous faire réfléchir à deux fois avant d'utiliser cette fonctionnalité.

Le Documentation officielle se lit comme suit:

Une utilisation inappropriée de innerHTML peut vous exposer à une attaque par script intersite (XSS). La désinfection des entrées utilisateur pour l'affichage est notoirement sujette aux erreurs, et l'échec de la désinfection correcte est l'une des principales causes de vulnérabilités Web sur Internet.

Découvrez ceci Démo ou l'extrait ci-dessous.

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. Récupérer le HTML depuis une source externe

Notez que l'exemple ci-dessus n'obtient pas le code HTML d'un fichier externe, mais qu'il est entré directement sous forme de chaîne. 

Un moyen simple de rechercher dynamiquement un fichier spécifique consiste à laisser votre serveur (par exemple, php) lire le fichier depuis un dossier local, analyser le texte et le renvoyer via une demande AJAX.

Exemple

//Your React component
fetchExternalHTML: function(fileName) {
  Ajax.getJSON('/myAPI/getExternalHTML/' + fileName).then(
    response => {
      this.setState({
        extHTML: response
      });
    }, err => {
      //handle your error here
    }
  );
}
17
Chris

La réponse de Chris était bonne, mais il fallait encore creuser pour que cela fonctionne. Voici les étapes à suivre:

Ajoutez le chargeur html à votre projet:

npm i -D html-loader

Ajoutez la règle suivante à votre fichier webpack.config:

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

Maintenant, vous pouvez importer votre fichier HTML comme suit:

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} />)
}}
7
iMad

Vous pouvez essayer react-templates . C'est "le" meilleur disponible. Vous pouvez avoir votre modèle en tant que fichier externe et le charger quand vous le souhaitez. Il sera rendu comme un charme avec toutes les API React disponibles.

J'espère que ça aide.

0
Pranesh Ravi