Javascript 使用客户端和服务器端渲染对同构组件进行反应

Javascript 使用客户端和服务器端渲染对同构组件进行反应,javascript,css,reactjs,react-router,react-dom-server,Javascript,Css,Reactjs,React Router,React Dom Server,我想创建一个既有客户端渲染又有服务器端渲染的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() {

我想创建一个既有客户端渲染又有服务器端渲染的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>
        )
    }
}
我的问题是:

我用
ReactDom.renderToString
reactrouter
搜索了一些服务器端渲染示例。但是,没有关于客户端和服务器端渲染的教程

我想要实现的是,客户端首先加载并呈现组件
,然后从服务器端加载

另一个问题是,如何使用renderString加载style module Record.css,因为我认为在这个renderString中,可以只加载html内容而不是css。

使用。它与babel register类似,但用于.css文件。基本上,它将require('Record.css')转换为基于钩子配置的javascript对象。所以你的钩子配置应该和你的网页css加载器配置相同

将其放入服务器的条目文件中

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

hook({/* config */});

当人们提到服务器端渲染时,他们通常指的是顶级应用程序在特定路径上的初始渲染,而不是单个组件

我很难理解您的用例是否符合您的要求。您的React应用程序是一棵由
片段组成的大树,因此在服务器端呈现单个组件是没有意义的。如果希望
Record
成为React的一部分,那么客户端需要了解它,那么为什么不按照常规在客户端渲染它呢

如果您真的需要在服务器端呈现它,那么我想您可以构建记录组件,以便它执行AJAX请求,然后可以使用呈现返回的html,但我不建议这样做

我的猜测是,
Record
需要来自服务器端的某种数据,这就是为什么要在那里渲染它?相反,只需将该数据作为JSON获取,并使用它来呈现组件客户端


读了你的评论,我知道你想做什么。您想要的是动态地从服务器加载内容(而不是呈现的html),以响应某些事件(向下滚动、单击按钮或其他)。React在这方面很在行。通过更改应用程序的状态(即有哪些记录),React将有效地处理重新提交

这是一个非常简单的应用程序。它首先有两个应该呈现的项(foo和bar)。作为对某个操作的响应(在本例中为单击按钮),会将更多数据加载到状态中,从而呈现到页面中。您所需要做的就是修改它,这样您就不用使用
setTimeout
而是对后端进行AJAX调用,以获取实际数据

现场版本:

类应用程序扩展React.Component{
建造师(道具){
超级(道具);
//从2条记录开始
此.state={
记录:[
{
名称:“foo”,
描述:“一些食物”
},
{
名称:'酒吧',
描述:“一些酒吧”
}
]
};
//绑定处理程序
this.loadmorecords=this.loadmorecords.bind(this);
}
//方法调用,该方法可按需获取更多记录
//这里我只使用setTimeout和一些静态数据,但在您的情况下
//这将是AJAX,用于从回调所在的服务器获取数据
//我会做设置状态。我用2秒的延迟来放大延迟
//来自服务器的数据。
loadmorecords(){
设置超时(()=>{
这是我的国家({
记录:this.state.records.concat([
{
姓名:'你好',
描述:'一些新加载的hello'
},
{
名称:“世界”,
描述:“一些新加载的世界”
}
])
})
}, 2000);
}
//方法来呈现当前处于状态的任何记录
渲染记录(){
const{records}=this.state;
返回记录。映射(记录=>{
返回(
  • {`${record.name}-${record.description}`}
  • ); }) } //React的渲染方法 render(){ 返回( 记录列表页
      {this.renderRecords()}
    ); } } /* *将上述组件渲染到div#应用程序中 */ ReactDOM.render(,document.getElementById('app'));
    我想要异步加载组件的客户端和服务器端呈现。客户端最初呈现react应用程序的主框架,然后从服务器加载子组件。是的,我理解,但react不是这样工作的。如果您提供更多的上下文并解释为什么客户端呈现记录对您不起作用,可能会更好。下面是我的一个例子:React应用程序中有100多个组件。我不希望它们在第一次呈现时呈现,因为它们是在用户拖动浏览器中带有一些触发事件的页面时呈现的。大多数用户主要关注前几个组件。所以我认为这可以节省brandwidth和cpu时间。这正是React擅长的,我已经更新了我的答案。这里的关键是客户端应该始终进行渲染,但您可以从服务器获取需要渲染的内容。在上面的例子中,我使用setTimeout模拟AJAX调用。
    const hook = require('css-modules-require-hook');
    
    hook({/* config */});
    
    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'));