我用服务器端渲染和2条路由设置了一个React路由器,一条路由应该将我重定向到当前“ / popular / php”的某个页面,但这不起作用,它不会将我重定向到任何地方,如果我删除重定向组件并仅在“ /”路径上呈现某些内容,则该方法有效。
我有这个路由文件。
import Home from './Home.js';
import Grid from './Grid.js';
import { fetchPopularRepos } from './api';
const routes = [
{
path: '/popular/:id',
component: Grid,
fetchInitialData: (path = '') => fetchPopularRepos (
path.split('/').pop()
)
}
]
export default routes
这是完成路由的App组件。如果我没记错的话,如果我点击“ /” URL,重定向组件应该会将我发送到“ / popular / php”页面,但是当我点击“ /” URL时什么也没有发生。
import React from 'react';
import Grid from './Grid.js';
import routes from './routes';
import { Route, Switch, Redirect } from 'react-router-dom'
import Navbar from './Navbar';
import Login from './Login';
class App extends React.Component {
render() {
return (
<div>
<Navbar />
<Switch>
<Route exact path="/" render={() => (
<Redirect to="/popular/php"/>)} />
{routes.map(({ path, exact, component: C, ...rest }) => (
<Route
key={path}
path={path}
exact={exact}
render={(props) => (
<C {...props} {...rest} />
)}
/>
))}
</Switch>
</div>
)
}
}
export default App
Server.js
import express from 'express';
import cors from 'cors';
import { renderToString } from 'react-dom/server';
import App from '../shared/App.js';
import React from 'react';
import serialize from 'serialize-javascript';
import { matchPath, StaticRouter } from 'react-router-dom';
import routes from '../shared/routes.js';
const app = express();
app.use(cors());
app.use(express.static('public'));
app.get('*', (req, res, next) => {
const activeRoute = routes.find(
(route) => matchPath(req.url, route)) || {};
const promise = activeRoute.fetchInitialData ?
activeRoute.fetchInitialData(req.path)
: Promise.resolve();
promise.then((data) => {
const context = { data };
const markup = renderToString(
<StaticRouter location={req.url} context={ context }>
<App />
</StaticRouter>);
res.send(`<!DOCTYPE html>
<html>
<head>
<title>SSR with RR</title>
<script src="/bundle.js"></script>
<script>window.__INITIAL_DATA__ = ${serialize(data)}</script>
</head>
<body>
<div id="app">${markup}</div>
</body>
</html>`)
}).catch(next);
})
app.listen(3000, () => {
console.log("Server is running on port 3000");
})
答案 0 :(得分:0)
将应用呈现为字符串后,您必须检查context
,并查看是否发生了重定向。如果确实如此,则您必须自己进行服务器重定向。
app.get("*", (req, res, next) => {
const activeRoute = routes.find(route => matchPath(req.url, route)) || {};
const promise = activeRoute.fetchInitialData
? activeRoute.fetchInitialData(req.path)
: Promise.resolve();
promise
.then(data => {
const context = { data };
const markup = renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);
if (context.url) {
res.redirect(301, context.url);
return;
}
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>SSR with RR</title>
<script src="/bundle.js"></script>
<script>window.__INITIAL_DATA__ = ${serialize(data)}</script>
</head>
<body>
<div id="app">${markup}</div>
</body>
</html>
`);
})
.catch(next);
});