web-dev-qa-db-ja.com

React:外部HTMLファイルをロードしてレンダリングする方法は?

ReactとReduxを使用して小さなブログアプリを構築しています。ブログには、投稿のタイトル、作成者、タグ、説明を含む投稿ページが表示されます。タイトルまたは「続きを読む」ボタンをクリックすると、すべての投稿を含むローカルプロジェクトのデータフォルダーから、対応する投稿を含むHTMLファイルを読み込んでレンダリングします。

Reduxはブログの状態を管理し、データフォルダー内の対応するhtmlファイルのhtmlPathを含む、8つの異なる投稿を含む初期のposts.jsonファイルを読み込みます。

20
Intermundos

私が見る方法は、あなたがここで解決する2つの問題があるということです。 1つ目は、Reactで要素のinnerHTMLを設定する方法です。もう1つは、特定のHTML(現在のルート、テキストフィールドの入力など)に応じて特定のHTMLをレンダリングする方法です。

1.要素のinnerHTMLの設定

dangerouslySetInnerHTMLプロップを使用してこれを行うことができます。名前が示すように、この要素のinnerHTMLを指定したものに設定します...そしてはい、「危険」は、この機能を使用する前に二度考えさせるために正確です。

Official Documentation は次のように読み取ります。

InnerHTMLを不適切に使用すると、クロスサイトスクリプティング(XSS)攻撃を受ける可能性があります。表示のためのユーザー入力のサニタイズはエラーが発生しやすいことで有名であり、適切にサニタイズしないことは、インターネット上のWeb脆弱性の主な原因の1つです。

これを確認してください Demo または以下のスニペット。

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.外部ソースからHTMLを取得する

上記の例は実際には外部ファイルからHTMLを取得するのではなく、文字列として直接入力されることに注意してください。

特定のファイルを動的にフェッチする簡単な方法の1つは、バックエンド(phpなど)がローカルフォルダーからファイルを読み取り、テキストを解析し、AJAXリクエストを介して送り返すことです。

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

クリスの答えは良かったが、それを機能させるにはさらに掘り下げる必要があった。実行する必要がある手順は次のとおりです。

プロジェクトにhtmlローダーを追加します。

npm i -D html-loader

Webpack.configファイルに次のルールを追加します。

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

これで、次のようにhtmlファイルをインポートできます。

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
Adam Boostani

react-templates を試すことができます。これが利用可能な「最高」です。テンプレートを外部ファイルとして使用し、いつでも好きなときに読み込むことができ、すべてのReact AP​​Iを使用できるようになります。

それが役に立てば幸い。

0
Pranesh Ravi