我們已經(jīng)熟悉React 服務(wù)端渲染(SSR)的基本步驟,現(xiàn)在讓我們更進(jìn)一步利用 React RouterV4 實(shí)現(xiàn)客戶端和服務(wù)端的同構(gòu)。畢竟大多數(shù)的應(yīng)用都需要用到web前端路由器,所以要讓SSR能夠正常的運(yùn)行,了解路由器的設(shè)置是十分有必要的
基本步驟
路由器配置
前言已經(jīng)簡單的介紹了React SSR,首先我們需要添加ReactRouter4到我們的項(xiàng)目中
$ yarn add react-router-dom# or, using npm$ npm install react-router-dom
接著我們會(huì)描述一個(gè)簡單的場景,其中組件是靜態(tài)的且不需要去獲取外部數(shù)據(jù)。我們會(huì)在這個(gè)基礎(chǔ)之上去了解如何完成取到數(shù)據(jù)的服務(wù)端渲染。
在客戶端,我們只需像以前一樣將我們的的App組件通過ReactRouter的BrowserRouter來包起來。
src/index.js
import React from 'react';import ReactDOM from 'react-dom';import { BrowserRouter } from 'react-router-dom';import App from './App';ReactDOM.hydrate( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById('root'));在服務(wù)端我們將采取類似的方式,但是改為使用無狀態(tài)的 StaticRouter
server/index.js
app.get('/*', (req, res) => { const context = {}; const app = ReactDOMServer.renderToString( <StaticRouter location={req.url} context={context}> <App /> </StaticRouter> ); const indexFile = path.resolve('./build/index.html'); fs.readFile(indexFile, 'utf8', (err, data) => { if (err) { console.error('Something went wrong:', err); return res.status(500).send('Oops, better luck next time!'); } return res.send( data.replace('<div id="root"></div>', `<div id="root">${app}</div>`) ); });});app.listen(PORT, () => { console.log(`😎 Server is listening on port ${PORT}`);});StaticRouter組件需要 location和context屬性。我們傳遞當(dāng)前的url(Express req.url)給location,設(shè)置一個(gè)空對(duì)象給context。context對(duì)象用于存儲(chǔ)特定的路由信息,這個(gè)信息將會(huì)以staticContext的形式傳遞給組件
運(yùn)行一下程序看看結(jié)果是否我們所預(yù)期的,我們給App組件添加一些路由信息
src/App.js
import React from 'react';import { Route, Switch, NavLink } from 'react-router-dom';import Home from './Home';import Posts from './Posts';import Todos from './Todos';import NotFound from './NotFound';export default props => { return ( <div> <ul> <li> <NavLink to="/">Home</NavLink> </li> <li> <NavLink to="/todos">Todos</NavLink> </li> <li> <NavLink to="/posts">Posts</NavLink> </li> </ul> <Switch> <Route exact path="/" render={props => <Home name="Alligator.io" {...props} />} /> <Route path="/todos" component={Todos} /> <Route path="/posts" component={Posts} /> <Route component={NotFound} /> </Switch> </div> );};
新聞熱點(diǎn)
疑難解答
圖片精選