- react-router-dom和react-router的区别:前者基于react-router,提供更多的功能。除了react-router中提供的{ switch,Router, Route }之外,还有{ Link,BrowserRouter,HashRouter,StaticRouter }等,其中Router是一个通用的低阶接口,通常情况下我们的程序只会使用其中一个高阶Router
- 具体可以参考https://segmentfault.com/a/1190000014294604
- 我们的架构采用浏览器BrowserRouter,服务端使用StaticRouter
- BrowserRouter 客户端 可以感知路由变化
- staticRouter context={{}}添加属性存储渲染信息,必传,服务端感知不到url的变化,所以需要拿到请求的路径 location={req.path}
- link 相当于一个a链接进行跳转
//创建router.js import Home from './containers/Home' import Login from './containers/Login' const Router = () => { return ( <div> <Route path="/" exact component={Home}></Route> <Route path="/Login" exact component={Login}></Route> </div> ) } export default Router;
//客户端路由 import { BrowserRouter } from 'react-router-dom' import Router from '../router' const App = () => { return( <BrowserRouter> <Router/> </BrowserRouter> ) } ReactDom.hydrate( <App/>, document.getElementById("root") )
//服务端路由 匹配路径记得改为* import { renderToString } from 'react-dom/server' import {StaticRouter} from 'react-router-dom'; import Router from '../router'; app.use(express.static('public')); app.get("*",(req,res)=>{ const content = renderToString( <StaticRouter context={{}} location={req.path}> <Router/> </StaticRouter> ) res.send(`<html> <head> <title>服务端渲染</title> </head> <body> <div id="root">${content}</div> </body> <script src="./index.js"></script> </html>`) })
- 会发现使用link进行跳转,react同构 服务器端渲染只发生在第一次进入页面的时候 也就是第一个页面是服务端渲染 其余页面由客户端加载的js接管(直接在浏览器地址栏改变url相当于重新进入一次页面,所以还是会请求html)
- untils优化代码,可以抽离出服务端路由匹配
项目地址:git@github.com:longlongdan/Reactssr.git