我很难弄清楚我们应该怎样做才能使React同构。我正在学习一些教程,这就是我现在所拥有的:
server.js
文件router.js
文件,我创建了一个Express Router对象,导入了ReactRouter
(react-router
)和ReactDOMServer
(react-dom/server
),然后我设置一个Express路由(router.get('*')
),用于获取ReactRouter,试图找到要呈现的路由(ReactRouter.match
)ReactRouter
指令的allRoutes.js文件。我设置了两个路径,/
和/about
Main
和About
,每个组件都有一个按钮和一个点击事件。 Main
必须在' /'中呈现和关于' / about'。这两个组件都有HTML
,HEAD
和BODY
标记,并且它们会重新发送到bundle.js
bundle.js
我遇到了几个问题,第一个是:
Main正确呈现并且Javascript工作正常,但转到localhost:3000/about
,页面加载需要5秒钟,加载时没有javascript行为,我得到校验和错误。
从/关闭删除bundle.js解决了校验和和繁重的加载问题,但没有Javascript行为
从allRoutes.js捆绑没有出现如上所述的错误,但我没有在页面中使用javascript(虽然它是用bundle.js编写的)
设置/关于/的子路径,因为Main不会导致问题,所以从不加载About组件。如果路由匹配,则服务器仅呈现Main。
正如我计划的那样,但我不确定这是实现同构行为应该做的事情,我在每个根组件About和Main中创建一个完整的HTML页面。在我看来,SEO更友好。
我做错了吗?
app.js
var React = require('react');
var ReactDOM = require('react-dom');
var Main = require('./components/Main');
ReactDOM.render(React.createElement(Main),document);
router.js
var express = require('express');
var router = express.Router();
var ReactRouter = require('react-router');
var ReactDOMServer = require('react-dom/server');
var Main = require('./components/Main');
var About = require('./components/About');
var React = require('react');
var routes = require('./routes');
router.get('*', function (req, res) {
var props = {};
ReactRouter.match({
routes: (
routes
),
location: req.url
}, function (error, redirectLocation, renderProps) {
console.log(renderProps)
if (renderProps) {
// se encontrou uma rota, responde o HTML referente ao componente que foi preprocessado no backend
res.send(ReactDOMServer.renderToString(
<ReactRouter.RouterContext {...renderProps} createElement={
function(Component,renderProps){
return <Component {...renderProps} {...props} />
}
} />
));
} else {
res.status(404).send('Not found');
}
});
});
module.exports = router;
routes.js
//routes.js
var ReactRouter = require('react-router');
var React = require('react');
var Main = require('./components/Main');
var About = require('./components/About');
module.exports = (
<ReactRouter.Router history={ ReactRouter.browserHistory }>
<ReactRouter.Route path='/' component={ Main } />
<ReactRouter.Route path='/about' component={ About } />
</ReactRouter.Router>
);
的WebPack
module.exports = {
entry: './routes.js',
output: {
filename: './bundle.js',
path: 'public'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['react']
}
}
]
}
};
about.js
var React = require('react');
module.exports = React.createClass({
_handleClick: function(){
alert('Sobre!');
},
render: function(){
return (
<html>
<head>
<link rel='stylesheet' href='/style.css' />
</head>
<body>
<h1>About</h1>
<button onClick={ this._handleClick }>About</button>
<script src='/bundle.js'></script>
</body>
</html>
);
}
});
server.js
require('babel-register')({
presets: ['react']
});
var React = require('react');
var ReactDOMServer = require('react-dom/server');
var express = require('express');
var app = express();
app.use(express.static('./public'));
app.use(require('./router'));
app.listen(3000,function(){
console.log('Started at 3000');
});
@editing
我将allRoutes(routes.js)更改为此。
<ReactRouter.Router history={ ReactRouter.browserHistory }>
<ReactRouter.Route path='/' component={ Main } >
<ReactRouter.Route path='about' component={ About } />
</ReactRouter.Route>
</ReactRouter.Router>
现在关于是Main的孩子,Javascript在Main工作,但是从未加载About。尝试访问不存在的路由会显示404,但映射的任何路由都会呈现Main。到底是怎么回事?
@resolved 找到了解决方案: