2016-09-01 23 views
3

クライアント側とサーバー側のレンダリングの両方で反応型アプリケーションを作成したいと考えています。ここでクライアント側とサーバー側のレンダリングの両方で同型コンポーネントに反応する

は一例です。このコンポーネントMain

import styles from './Main.css'; 

import React, {Component} from 'react'; 
import Info from './Info/Info'; 
import Record from './Record/Record' 

export default class Main extends Component { 
    render() { 
     return (
      <div className={styles.main}> 
       <div className={styles.mainIn + ' clearfix'}> 
        <div className={styles.mainLeft}> 
         <Info info_num="2012201972"/> 
        </div> 
        <div className={styles.mainRight}> 
         <div className="clearfix mb20"> 
          <Record /> 
         </div> 
        </div> 
       </div> 
      </div> 
     ) 
    } 
} 

、それは<Record />

コンポーネントここでRecord

import styles from './Record.css'; 
import layout from '../../shared/styles/layout.css' 

import React, {Component} from 'react'; 

export default class Record extends Component { 
    render() { 
     return (
      <div className="float_two"> 
       <div className={layout.box + ' mr10'}> 
        This is Record! 
       </div> 
      <div> 
     ) 
    } 
} 

除いて、クライアント側でレンダリングする必要が私の質問です:

私はReactDom.renderToStringreact-routerでサーバー側レンダリングの例のいくつかの例を検索しました。ただし、クライアント側とサーバー側の両方のレンダリングに関するチュートリアルはありません。

私が達成したいのは、クライアントはまずコンポーネント<Main />をロードしてレンダリングし、サーバ側から<Record />をロードします。

もう一つの質問は、renderToStringでスタイルモジュールのRecord.cssをロードする方法です。なぜなら、このrenderToStringで考えると、CSS以外のhtmlをロードできるからです。

答えて

2

人々はサーバー側のレンダリングを参照するとき、通常、個々のコンポーネントではなく特定のルートでの最上位アプリケーションの最初のレンダリングを参照しています。

あなたのご要望がユースケースを理解するのに問題があります。あなたのReactアプリケーションは大きなツリーの1つで、Fragmentsなので、サーバー側の単一コンポーネントをレンダリングすることは実際には意味がありません。 RecordをReactに含めるには、クライアントはそれについて知る必要があります。なぜなら、クライアント側でいつものようにレンダリングしてみませんか?

本当にサーバーサイドでレンダリングする必要がある場合は、レコードコンポーネントを構築してAJAXリクエストを作成し、返されたhtmlをhttps://facebook.github.io/react/tips/dangerously-set-inner-html.htmlでレンダリングできると思いますが、お勧めしません。

私の推測では、Recordにはサーバー側から何らかのデータが必要なので、そこにレンダリングしたいのですか?代わりにJSONとしてそのデータを取得し、それを使用してコンポーネントのクライアント側をレンダリングします。


あなたのコメントを読んで、私はあなたが何をしようとしているのか知っています。何が必要なのは、何らかのイベント(スクロールダウン、ボタンクリックなど)に応答して、サーバーからコンテンツ(動的にレンダリングされない)を動的にロードすることです。反応はこれで非常に良いです。 Reactは、アプリケーションの状態(つまり、そこにあるレコード)を変更することで、効率的に再レン​​ダリングを行います。

これは非常に単純なアプリケーションです。それはレンダリングすべき2つの項目(fooとbar)を持つことから始まります。アクション(この場合はボタンクリック)に応答して、より多くのデータが状態にロードされ、ページにレンダリングされます。 setTimeoutの代わりに、実際のデータを取得するためにバックエンドにAJAXコールを行うように、これを変更するだけです。ここ

ライブバージョン:https://codepen.io/dpwrussell/pen/qadrko

class Application extends React.Component { 

    constructor(props) { 
    super(props); 

    // Start with 2 records 
    this.state = { 
     records: [ 
     { 
      name: 'foo', 
      description: 'Some foo' 
     }, 
     { 
      name: 'bar', 
      description: 'Some bar' 
     } 
     ] 
    }; 

    // Bind handlers 
    this.loadMoreRecords = this.loadMoreRecords.bind(this); 
    } 

    // Method to call which gets more records on demand 
    // Here I just use setTimeout and some static data, but in your case 
    // this would be AJAX to get the data from your server where the callback 
    // would do the setState. I use a 2 second delay to exaggerate a delay getting 
    // the data from the server. 
    loadMoreRecords() { 
    setTimeout(() => { 
     this.setState({ 
     records: this.state.records.concat([ 
      { 
      name: 'hello', 
      description: 'Some newly loaded hello' 
      }, 
      { 
      name: 'world', 
      description: 'Some newly loaded world' 
      } 
     ]) 
     }) 
    }, 2000); 
    } 

    // Method to render whatever records are currently in the state 
    renderRecords() { 
    const { records } = this.state; 
    return records.map(record => { 
     return (
     <li>{ `${record.name} - ${record.description}` }</li> 
    ); 
    }) 
    } 

    // React's render method 
    render() { 
    return (
     <div> 
     <h1>List of Records Page</h1> 
     <ul> 
      { this.renderRecords() } 
     </ul> 
     <input type='button' onClick={this.loadMoreRecords} value='Load more Records' /> 
     </div> 
    ); 
    } 
} 

/* 
* Render the above component into the div#app 
*/ 
ReactDOM.render(<Application />, document.getElementById('app')); 
+0

私は非同期ロードコンポーネント用の両方のクライアント側とサーバー側のレンダリングをしたいです。クライアントは最初に反応するアプリケーションのメインフレームワークをレンダリングし、サーバーからサブコンポーネントを読み込みます。 – chenatu

+0

はい、私はそれを理解していますが、それはReactの仕組みではありません。もしあなたがもっと文脈を与えて、レコードのクライアント側のレンダリングがなぜあなたにとってうまくいかないのかを説明したとします。 – dpwrussell

+0

私のケースの1つです:React Appには100以上のコンポーネントがあります。私は最初にレンダリングしたくないのですが、ユーザーがいくつかのトリガーされたイベントでブラウザーのページをドラッグ・ダウンするとレンダリングされます。ユーザーのほとんどは、最初の数少ないコンポーネントに主に焦点を当てています。だから私はこれがブランド幅とCPU時間を節約できると思う。 – chenatu

0

css-modules-require-hookを使用してください。これはbabel-registerと似ていますが、.cssファイルに似ています。基本的には、あなたの要求( 'Record.css')をフック設定のjavascriptオブジェクトベースに変換します。だからあなたのフックの設定はあなたのwebpack css-loaderの設定と同じでなければなりません。

サーバーのエントリファイルに入れます。

const hook = require('css-modules-require-hook'); 

hook({/* config */}); 
関連する問題