我正在尝试使用react-router 4.0.0设置通用反应应用。
服务器端呈现的工作原理除了我的链接标记在服务器和客户端上呈现的方式不同。以下是错误消息:
警告:React尝试在容器中重用标记,但校验和无效。这通常意味着您正在使用服务器呈现,并且在服务器上生成的标记不是客户端所期望的。 React注入了新的标记以补偿哪些有效但你已经失去了服务器渲染的许多好处。相反,弄清楚为什么生成的标记在客户端或服务器上是不同的:
(client) o Furb</h1><a href="./" data-reactid="4" (server) o Furb</h1><a href="/./" data-reactid="4
我很反应 - 路由器并且反应一般,所以请记住,这可能是我的代码中的一个微不足道的错误。另外,我一直在学习,所以,我的代码中可能存在其他吵闹的错误,提前抱歉。
在线查看我想出了一个包含类似问题的错误修复:https://github.com/ReactTraining/react-router/pull/4484
但是,这个补丁包含在react-router 4.0.0中(我查了代码并且它确实已修复)。因此,我的问题不能由此造成。
经过大量的修修补补后,我怀疑我的配置或因我对自己所做的事情的理解有限而产生的错误。例如,对于StaticRouter,我使用location={req.originalUrl}
代替location={req.url}
而req.url
似乎总是/
,我不确定原因。
我发布了我认为相关的文件,但如果您想查看完整代码,可以在此处找到:https://github.com/magp/furb/tree/universal
的package.json
{
"name": "furb",
"version": "0.0.1",
"description": "A boilerplate for Firebase-UniversalRedux-Bootstrap/MaterialUI projects",
"main": "app/server.jsx",
"scripts": {
"start": "concurrently --kill-others \"npm run start:api\" \"npm run start:back\"",
"start:back": "node app/serverlauncher.js",
"start:api": "node api/server.js",
"clean": "rimraf static",
"serve:prod": "http-server ./static -o -p 3032",
"build:app": "NODE_ENV=production webpack --config config/webpack-prod-config.js",
"build": "npm run clean && npm run build:app && npm run serve:prod",
"test": "echo 'NODE_ENV=production mocha './tests/**/*.spec.js' --compilers js:babel-core/register'",
"lint": "eslint --config=./.eslintrc app/**/**/*.jsx"
},
"repository": {
"type": "git",
"url": "git+https://github.com/magp/furb.git"
},
"keywords": [
"Boilerplate",
"React",
"Redux",
"UniversalJS",
"Bootstrap",
"MaterialUI"
],
"author": "magp",
"license": "MIT",
"bugs": {
"url": "https://github.com/magp/furb/issues"
},
"homepage": "https://github.com/magp/furb#readme",
"dependencies": {
"express": "^4.15.2",
"history": "^4.6.1",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-hot-loader": "^3.0.0-beta.6",
"react-router-dom": "^4.0.0"
},
"devDependencies": {
"babel-core": "^6.24.0",
"babel-loader": "^6.4.0",
"babel-preset-es2015": "^6.24.0",
"babel-preset-react": "^6.23.0",
"concurrently": "^3.4.0",
"eslint": "^3.17.1",
"eslint-config-airbnb": "^14.1.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-react": "^6.10.0",
"html-webpack-plugin": "^2.28.0",
"http-server": "^0.9.0",
"node-sass": "^4.5.0",
"rimraf": "^2.6.1",
"sass-loader": "^6.0.3",
"style-loader": "^0.14.0",
"webpack": "^2.2.1",
"webpack-dev-middleware": "^1.10.1",
"webpack-hot-middleware": "^2.17.1"
}
}
应用程序/ serverlauncher.js
require('babel-register')({
presets: [ 'es2015', 'react' ]
});
var app = require('./server.jsx');
应用程序/ server.jsx
var path = require('path');
var express = require('express');
var React = require('react');
var ReactDOMServer = require('react-dom/server');
var StaticRouter = require('react-router-dom/StaticRouter').default;
var webpack = require('webpack');
var config = require('../config/webpack-dev-config');
var Routes = require('./routes/Routes.jsx').default;
var app = express();
var compiler = webpack(config);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath
}));
app.use(require('webpack-hot-middleware')(compiler));
const routes = [
'/',
'/about'
];
app.use('*', function (req, res, next) {
const context = {};
const componentHTML = ReactDOMServer.renderToString(<StaticRouter context={context} location={req.originalUrl}><Routes /></StaticRouter>);
const HTML = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Static</title>
</head>
<body>
<div id="app">${componentHTML}</div>
<script type="text/javascript" src="/static/source.js"></script>
</body>
</html>
`;
res.end(HTML);
});
const PORT = process.env.PORT || 3030;
app.listen(PORT, 'localhost', function(err) {
if (err) {
console.log(err);
return;
}
console.log('Listening at http://localhost:3030');
});
应用程序/路由/ Routes.jsx
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import List from '../components/List';
import About from '../components/About';
import NotFound from '../components/NotFound';
import links from '../../api/data/links.json';
const linksarr = Object.keys(links).map(function(k) { return links[k] });
function Routes() {
return (
<Switch>
<Route exact path="/" render={props => (<List links={linksarr} {...props} />)} />
<Route exact path="/about" component={About} />
<Route component={NotFound} />
</Switch>
);
}
export default Routes;
应用/组件/ Layout.jsx
import React from 'react';
import { Link } from 'react-router-dom';
function Layout() {
return (
<div>
<h1>Welcome to Furb</h1>
<Link to="./">Home</Link>
<Link to="./about">About</Link>
<Link to="./test">Test</Link>
</div>
);
}
export default Layout;
请原谅这个冗长的问题,并提前感谢您提供任何帮助。
答案 0 :(得分:1)
尝试将&#34;中的句号删除到&#34;你的链接领域。它应该只是&#34; /&#34;,&#34; / about&#34;等等,而不是&#34; ./ about&#34;。路由不是文件路径,路由器会对它们进行解析和解释,并且这些时间段会让人感到困惑。
import React from 'react';
import { Link } from 'react-router-dom';
function Layout() {
return (
<div>
<h1>Welcome to Furb</h1>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/test">Test</Link>
</div>
);
}
export default Layout;