我的应用代码在这里:https://github.com/WebTerminator/aldemar/commits/master
我正在努力让我的反应应用程序在服务器端工作,在这个阶段它部分工作。
我遇到的问题是:(sam问题发生在localhost上)
如果我在浏览器中导航它一切正常,我刷新此URL的时刻https://aldemar-productions.herokuapp.com/projects/margam2我收到如下控制台错误:
如果我刷新其他网址,例如“https://aldemar-productions.herokuapp.com/projects”或“https://aldemar-productions.herokuapp.com/about”,则可以正常使用。
server.js
import express from 'express';
import path from 'path';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import routes from './src/client/app/config/routes.jsx';
let port = process.env.PORT || 8080;
let app = express();
app.use(express.static('src/client/'));
// app.get('/', (req, res) => {
// res.sendFile(path.resolve(__dirname + '/src/client/index.html'))
// });
app.get('*', (req, res) => {
match(
{ routes, location: req.url },
(err, redirectLocation, renderProps) => {
// in case of error display the error message
if (err) {
return res.status(500).send(err.message);
}
// in case of redirect propagate the redirect to the browser
if (redirectLocation) {
return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
}
// generate the React markup for the current route
let markup;
if (renderProps) {
// if the current route matched we have renderProps
markup = renderToString(<RouterContext {...renderProps}/>);
}
// else {
// // otherwise we can render a 404 page
// markup = renderToString(<NotFoundPage/>);
// res.status(404);
// }
// render the index template with the embedded React markup
return res.sendFile('index.html', {root : __dirname + '/src/client/'});
}
);
});
app.listen(port);
console.log('server started');
routes.jsx
import React from 'react';
import { Route, Router, browserHistory } from 'react-router';
import ReactDOM from 'react-dom';
import Wrapper from './../components/wrapper.jsx';
import Home from './../components/home.jsx';
import Projects from './../components/projects.jsx';
import SingleProject from './../components/projectContent/singleProject.jsx';
import About from './../components/aboutUs.jsx'
if(typeof window !== 'undefined') {
console.log('here baby');
ReactDOM.render((
<Router history={browserHistory} >
<Route component={Wrapper} >
<Route path="/" component={Home} />
<Route path="projects" component={Projects} />
<Route path="projects/:id" component={SingleProject} />
<Route path="about" component={About} />
</Route>
</Router>
), document.getElementById('app'));
}
singleProject.jsx(我从url获取ID参数以加载特定数据)
import React from 'react';
import Video from './../video.jsx';
import Overview from './overview.jsx';
import Photography from './photography.jsx';
import Details from './details.jsx';
import Cast from './cast.jsx';
import porgectsCollection from './../../data/projectInfo.js';
import { StickyContainer, Sticky } from 'react-sticky';
class Nav extends React.Component {
constructor(props) {
super(props);
this.state = {
mobileMenu: false
};
}
showMobileMenu () {
this.setState({ mobileMenu: !this.state.mobileMenu });
}
render () {
let links = this.props.project.links.map(function(el, i){
return <li key={i}>{el}</li>;
});
const open = this.state.mobileMenu ? ' open' : '';
return (
<Sticky stickyClassName="sticky-nav" topOffset={-100}>
<span onClick={this.showMobileMenu.bind(this)} className="mobile-trigger">X</span>
<nav className={"secondary-nav" + open}>
<ul>
{links}
</ul>
</nav>
</Sticky>
);
}
}
class SingleProject extends React.Component {
getProjectDataFromUrl() {
return **porgectsCollection.filter(el => el.title === this.props.params.id)**;
}
render () {
let data = this.getProjectDataFromUrl(),
project = data[0];
return (
<section className="project-page">
<StickyContainer>
<Video project={project} />
<Nav project={project} />
<Overview project={project} />
<Photography project={project} />
<Details project={project} />
<Cast project={project} />
</StickyContainer>
</section>
);
}
}
export default SingleProject;
当我点击这样的网址“https://aldemar-productions.herokuapp.com/projects/margam2”时,根据我的路线收集“margam2”:
<Route path="projects/:id" component={SingleProject} />
我根据该参数加载特定数据。我相信这个问题就在于做服务器端渲染。
UPDATE-1
在我的index.html的头部添加这个内容可以在我刷新页面时显示内容,但缺少CSS:
<base href="/" />
http://localhost:8080/css/style.css可以完全访问css,但是当我刷新“http://localhost:8080/projects/margam2”时,会显示内容但不显示css。
答案 0 :(得分:1)
经过2天的研究,这对我有所帮助:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
**<base href="/" />**
<link rel="stylesheet" href="./css/foundation.min.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet">
<link rel="stylesheet" href="./css/font-awesome.min.css">
<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" />
</head>
<body>
<div id="app"></div>
<script src="./public/bundle.js" type="text/javascript"></script>
</body>
</html>
然而我也在我的控制台中发现了这个:
browser.js:49警告:不推荐使用自动设置basename,将在下一个主要版本中删除。语义与basename略有不同。请在createHistory
选项中明确传递basename所以需要为此找到解决方案。
<强>更新-1 强>
我认为,甚至更好的解决方案。我已经相对于绝对更改了资产路径表单:查看每个本地资产前面的“/”
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="/css/foundation.min.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet">
<link rel="stylesheet" href="/css/font-awesome.min.css">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" />
</head>
<body>
<div id="app"></div>
<script src="/public/bundle.js" type="text/javascript"></script>
</body>
</html>
答案 1 :(得分:0)
在项目的页面上,您使用的是内联关闭div,如下所示:
<div id="app" />
在所有其他页面中,您使用的是空div
<div id="app" > </div>
这是正确的方法。
React-Router不会重新呈现您的网页,只会将您的反应代码“重新添加”到您的 id =“app”。
这就是为什么当你打开它点击它时工作,当你刷新它时,它就会崩溃。