服务器上的 React-router 始终呈现根路由
React-router on server always renders root route
我已经在这个问题上折腾了半天了,找不到问题所在。我在服务器上使用 react-router。但是对于每条路线,它都呈现相同的组件(来自根路线的那个)。
这是我的服务器:
//routes
import routes from "../shared/routes";
app.get('*', (request, response) => {
match({ routes: routes, location: request.url }, (err, redirect, props) => {
if (err) {
response.status(500).send(err.message)
} else if (redirect) {
response.status(302).redirect(redirect.pathname + redirect.search)
} else if (props) {
console.log('Rendering '+JSON.stringify(props));
const appHtml = ReactDOMServer.renderToString(<RouterContext {...props}/>);
response.render('app', {app: appHtml});
} else {
response.status(404).send('Not Found')
}
});
});
这是我的路线:
export default (
<Route component={AppHandler} path="/">
<IndexRoute component={AppHandler}/>
<Route component={AboutHandler} path="about" />
</Route>
);
其他观察:
- 它正确区分不存在的路线,例如。当我打字时
/blahblah 在浏览器中我得到 404
- 当我把 AboutHandler 作为
根路由组件,正确显示
- 我还尝试将“/about”作为路由路径,而不仅仅是 "about"
- 这是我在道具中得到的
{"routes":[{"path":"/","indexRoute":{},"childRoutes":[{"path":"about"}]},{"path":"about"}],"params":{},"location":{"pathname":"/about","search":"","hash":"","action":"POP","key":"bqces8","query":{}},"components":[null,null],"router":{"location":{"pathname":"/about","search":"","hash":"","action":"POP","key":"bqces8","query":{}},"params":{},"routes":[{"path":"/","indexRoute":{},"childRoutes":[{"path":"about"}]},{"path":"about"}]},"matchContext":{"transitionManager":{},"router":{"location":{"pathname":"/about","search":"","hash":"","action":"POP","key":"bqces8","query":{}},"params":{},"routes":[{"path":"/","indexRoute":{},"childRoutes":[{"path":"about"}]},{"path":"about"}]}}}
更新:
AppHandler 和 AboutHandler 是使用 webpack 构建的。它们的导入方式如下:
import AppHandler from '../../build/app';
import AboutHandler from '../../build/about';
以下是两个文件的相关部分:
app.js:
var App = function (_Component) {
_inherits(App, _Component);
function App() {
_classCallCheck(this, App);
return _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).apply(this, arguments));
}
_createClass(App, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
'App root'
);
}
}]);
return App;
}(_react.Component);
exports.default = App;
和about.js:
var About = function (_Component) {
_inherits(About, _Component);
function About() {
_classCallCheck(this, About);
return _possibleConstructorReturn(this, (About.__proto__ || Object.getPrototypeOf(About)).apply(this, arguments));
}
_createClass(About, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
'About'
);
}
}]);
return About;
}(_react.Component);
exports.default = About;
我误解了 react-router 中的嵌套路由,也误解了 AppHandler 中的 {this.props.children}
。
我已经在这个问题上折腾了半天了,找不到问题所在。我在服务器上使用 react-router。但是对于每条路线,它都呈现相同的组件(来自根路线的那个)。
这是我的服务器:
//routes
import routes from "../shared/routes";
app.get('*', (request, response) => {
match({ routes: routes, location: request.url }, (err, redirect, props) => {
if (err) {
response.status(500).send(err.message)
} else if (redirect) {
response.status(302).redirect(redirect.pathname + redirect.search)
} else if (props) {
console.log('Rendering '+JSON.stringify(props));
const appHtml = ReactDOMServer.renderToString(<RouterContext {...props}/>);
response.render('app', {app: appHtml});
} else {
response.status(404).send('Not Found')
}
});
});
这是我的路线:
export default (
<Route component={AppHandler} path="/">
<IndexRoute component={AppHandler}/>
<Route component={AboutHandler} path="about" />
</Route>
);
其他观察:
- 它正确区分不存在的路线,例如。当我打字时 /blahblah 在浏览器中我得到 404
- 当我把 AboutHandler 作为 根路由组件,正确显示
- 我还尝试将“/about”作为路由路径,而不仅仅是 "about"
- 这是我在道具中得到的
{"routes":[{"path":"/","indexRoute":{},"childRoutes":[{"path":"about"}]},{"path":"about"}],"params":{},"location":{"pathname":"/about","search":"","hash":"","action":"POP","key":"bqces8","query":{}},"components":[null,null],"router":{"location":{"pathname":"/about","search":"","hash":"","action":"POP","key":"bqces8","query":{}},"params":{},"routes":[{"path":"/","indexRoute":{},"childRoutes":[{"path":"about"}]},{"path":"about"}]},"matchContext":{"transitionManager":{},"router":{"location":{"pathname":"/about","search":"","hash":"","action":"POP","key":"bqces8","query":{}},"params":{},"routes":[{"path":"/","indexRoute":{},"childRoutes":[{"path":"about"}]},{"path":"about"}]}}}
更新:
AppHandler 和 AboutHandler 是使用 webpack 构建的。它们的导入方式如下:
import AppHandler from '../../build/app';
import AboutHandler from '../../build/about';
以下是两个文件的相关部分:
app.js:
var App = function (_Component) {
_inherits(App, _Component);
function App() {
_classCallCheck(this, App);
return _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).apply(this, arguments));
}
_createClass(App, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
'App root'
);
}
}]);
return App;
}(_react.Component);
exports.default = App;
和about.js:
var About = function (_Component) {
_inherits(About, _Component);
function About() {
_classCallCheck(this, About);
return _possibleConstructorReturn(this, (About.__proto__ || Object.getPrototypeOf(About)).apply(this, arguments));
}
_createClass(About, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
'About'
);
}
}]);
return About;
}(_react.Component);
exports.default = About;
我误解了 react-router 中的嵌套路由,也误解了 AppHandler 中的 {this.props.children}
。