簡體   English   中英

使用客戶端和服務器端呈現來反應同構組件

[英]React isomorphic component with both client-side and server-side rendering

我想創建一個具有客戶端和服務器端呈現的react應用程序。

這是一個例子:

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

在此組件Main ,除了<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搜索了服務器端渲染示例的一些示例。 但是,沒有客戶端和服務器端呈現的教程。

我想要實現的是,客戶端首先加載並呈現Component <Main /> ,然后從服務器端加載<Record />

另一個問題是,如何使用renderToString加載樣式模塊Record.css,因為我認為在這個renderToString中只能加載html而不是css。

當人們提到服務器端渲染時,他們通常指的是某個路徑上的頂級應用程序的初始渲染,而不是單個組件。

我無法理解您的用例是針對您的要求。 您的React應用程序是Fragments一個大樹,因此渲染單個組件服務器端並不真正有意義。 如果你想讓Record成為React的一部分,那么客戶端需要了解它,那么為什么不按照慣例在客戶端進行渲染呢?

如果你真的需要渲染它的服務器端,那么我猜你可以構建Record組件,以便它執行一個AJAX請求,然后返回的html可以使用https://facebook.github.io/react/tips/dangerously-呈現 - set-inner-html.html ,但我不推薦它。

我的猜測是, Record需要來自服務器端的某種數據,這就是為什么要在那里渲染它? 而只是將該數據作為JSON獲取並使用它來呈現組件客戶端。


讀完你的評論后,我知道你要做什么。 你想要的是從服務器動態加載內容(不是渲染的html)以響應某些事件(滾動,按鈕點擊或其他)。 React非常擅長這個。 通過更改應用程序的狀態(即有什么記錄),React將有效地處理重新渲染。

這是一個非常簡單的應用程序。 它首先要有兩個應該渲染的項目(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'));

使用css-modules-require-hook 它與babel-register類似,但是對於.css文件。 基本上,它會將您的require('Record.css')轉換為您的hook配置上的javascript Object。 所以你的鈎子配置應該與你的webpack css-loader配置相同。

將它放在服務器的入口文件中。

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

hook({/* config */});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM