自译: 如何使用服务器端渲染构建快速加载的React apps
英文原文 :How to build React apps that load quickly using server side rendering 我们知道客户端框架非常优秀,他能够帮助我们构建用户们喜爱的交互式的快速的web应用。 $ npm install babel react react-dom express jade
我们将要为我们的示例使用 express 和 jade 去创建服务端, react 和 react-dom 包 将会提供对React组件的服务端渲染的功能。 public/components.js
views/index.jade
app.js
component.js 将会包含我们的React 组件。index.jade将会提供基本的模版文件并会加载其全部JavaScript 。app.js将会是我们的Node服务器。 doctype
html
head
title React Server Side Rendering Example
body
div(id='react-root')!= react
script(src='https://fb.me/react-0.14.0.js')
script(src='https://fb.me/react-dom-0.14.0.js')
script(src='https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js')
script(src='/components.js',type='text/babel')
div(id=’react-root’)!= react 他的目的是包含React根组件,这个react 变量将会包含某些React组件被服务器端渲染之后的HTML。 require('babel/register')
var express = require('express'),app = express(),React = require('react'),ReactDOM = require('react-dom/server'),components = require('./public/components.js')
var HelloMessage = React.createFactory(components.HelloMessage)
app.engine('jade',require('jade').__express)
app.set('view engine','jade')
app.use(express.static(__dirname + '/public'))
app.get('/',function(req,res){
res.render('index',{
react: ReactDOM.renderToString(HelloMessage({name: "John"}))
})
})
app.listen(3000,function() {
console.log('Listening on port 3000...')
})
在你发起的所有快速应用程序中,大多数的文件都是这种方式。 require('babel/register')
加载Babel到你的组件。通过这,你可以直接require其他包含JSX的组件到你当前组件中, 接着他们被转化为JavaScript,就像下面两行。 var components = require('./public/components.js')
var HelloMessage = React.createFactory(components.HelloMessage)
第一行加载用JSX写的React组件。接着React.createFactory创建了一个函数,它能够创建HelloMessage组件。 app.get('/',{
react: ReactDOM.renderToString(HelloMessage({name: "John"}))
})
})
这就是React组件将被渲染的部分,接着一个页面被渲染,并发送到浏览器。 var isNode = typeof module !== 'undefined' && module.exports,React = isNode ? require('react') : window.React,ReactDOM = isNode ? require('react') : window.ReactDOM
var HelloMessage = React.createClass({
handleClick: function () {
alert('You clicked!')
},render: function() {
return <div onClick={this.handleClick}>Hello {this.props.name}</div>
}
})
if (isNode) {
exports.HelloMessage = HelloMessage
} else {
ReactDOM.render(<HelloMessage name="John" />,document.getElementById('react-root'))
}
正如你所看到的,它看起来很像其他组件,使用JSX,除了开头和结尾。这里是你应该所关注的去使你的组件在浏览器和Node中。 doctype
html
head
title React Server Side Rendering Example
body
div(id='react-root')!= react
script(src='https://fb.me/react-0.14.0.js')
script(src='https://fb.me/react-dom-0.14.0.js')
script(src='https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js')
script(src='http://code.jquery.com/jquery-2.1.3.js')
script(src='/components.js',type='text/babel')
我们的服务器(下面文件)将必须提供一个请求路径。 require('babel/register')
var express = require('express'),{
react: React.renderToString(HelloMessage({name: "John"}))
})
})
app.get('/name',res){
res.send("Paul," + new Date().toString())
})
app.listen(3000,function() {
console.log('Listening on port 3000...')
})
和上个样例的不同是下面三行: app.get('/name'," + new Date().toString())
})
他做的所有事是当请求/name ,将会返回一个带有当前日期的名为Paul的信息。让我们看看这个最有趣也是我们app最重要的一部分——这个React组件 var isNode = typeof module !== 'undefined' && module.exports,React = isNode ? require('react') : window.React,ReactDOM = isNode ? require('react-dom') : window.ReactDOM
var HelloMessage = React.createClass({
getInitialState: function () {
return {}
},loadServerData: function() {
$.get('/name',function(result) {
if (this.isMounted()) {
this.setState({name: result})
}
}.bind(this))
},componentDidMount: function () {
this.intervalID = setInterval(this.loadServerData,3000)
},componentWillUnmount: function() {
clearInterval(this.intervalID)
},handleClick: function () {
alert('You clicked!')
},render: function() {
var name = this.state.name ? this.state.name : this.props.name
return <div onClick={this.handleClick}>Hello {name}</div>
}
})
if (isNode) {
exports.HelloMessage = HelloMessage
} else {
ReactDOM.render(<HelloMessage name="John" />,document.getElementById('react-root'))
}
除了添加了四个小方法,其它的都和之前的相同。 getInitialState: function () {
return {}
},loadServerData: function() {
$.get('/name',function(result) {
if (this.isMounted()) {
this.setState({name: result})
}
}.bind(this))
},componentDidMount: function () {
this.intervalID = setInterval(this.loadServerData,3000)
},componentWillUnmount: function() {
clearInterval(this.intervalID)
},
一旦组件被挂载,那么每3秒它就会从/name请求获得一个 名字并展示它。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |