一个react项目在服务器端渲染,其实最本质的一个点就在于路由。路由一般采用的是react-router
。其实在react-router
里,它本身就提供了服务器端渲染的方法,下面对它进行一下小小的学习。
服务端渲染跟客户端渲染有点不同,因为,服务端渲染需要发送500/30x,还要在渲染前就要请求数据。
react-router
提供了两个更底层的api,一个是match
,另一个是RouterContext
。
match
是用来匹配路由的,但是它没有渲染的功能。
RouterContext
用来同步渲染components的。
看个例子:
import { renderToString } from 'react-dom/server'
import { match, RouterContext } from 'react-router'
import routes from './routes'
serve((req, res) => {
match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
res.status(200).send(renderToString(<RouterContext {...renderProps} />))
} else {
res.status(404).send('Not found')
}
})
})
这是一个非常简单的在服务端渲染例子,但是现在一个最重要的问题,就是如何传数据呢?
在react项目中,一般是用redux来进行数据的管理的。redux 里有个store维护的state状态树。那么在和api进行数据交互的时候,如何将数据放在store里面呢?
基本的思路就是,在createStore的时候,将与api交互的方法同时传入进去,这样,在store中的action可以调用那个库。调用库去请求数据,一般是个promise对象,取到数据之后,然后在reducer中将数据reduce进state树中。就完成了这个过程。
其实最最本质的,就是让action能去api请求数据,只要action请求到了数据并且能进入reducer,那就成功了。这个思路跟客户端渲染也没有什么区别。
在服务端渲染还有一个致命的报错。来自于webpack。
在client,webpack可以require()各种静态资源,但是在node 环境中,require()是只能用于javascript 的。
这里就要靠一个library了。
webpack-isomorphic-tools
具体的介绍在github中都有,也不在这里赘述。
另外再向大家推荐一个完整的react例子,里面有很多很多东西可以参考借鉴,甚至可以直接拿过来做自己的项目。
react栗子
网友评论