我是新的反应和反应路由器。该应用是使用create-react-app创建的。我需要在我的应用程序中实现两个主要页面的路由。我尝试了很多选项,最后使用以下代码。
此代码在开发过程中正常工作。但在构建应用程序后,它无法正常工作。到404页面的路线才会显示。请帮我解决这个问题。
<Router history={browserHistory}>
<Route component={Root}>
<IndexRoute component={App} />
<Route path="/" component={App} />
<Route path="/sna/:country" component={SNA} />
<Route path="*" component={FourOFour}/>
</Route>
</Router>
我已使用browserHistory
启用了使用以下代码更改下拉列表的导航。
selectCountry(event){
var value = event.target.value;
browserHistory.push('/sna/' + value);
}
{
"name": "my-app",
"version": "0.1.0",
"homepage": "./",
"private": true,
"dependencies": {
"bootstrap": "^3.3.7",
"react": "^15.4.2",
"react-addons-update": "^15.4.2",
"react-bootstrap": "^0.30.8",
"react-data-grid": "^2.0.24",
"react-dom": "^15.4.2",
"react-router": "^2.6.0"
},
"devDependencies": {
"react-scripts": "0.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
答案 0 :(得分:6)
在卡住react-router
几天之后,我会阅读React Training中的文档。然后我按照快速启动步骤修改它以满足我的要求。
import {
HashRouter as Router,
Route,
} from 'react-router-dom';
<Router>
<div>
<Header />
<Route exact path="/" component={Content} />
<Route path="/:country" component={SnaContent} />
<Footer />
</div>
</Router>
这已经解决了这个问题。希望它对面临类似问题的其他人有所帮助。
答案 1 :(得分:3)
首先,这不是React Router的问题。请注意,在您的package.json
中,您具有:
"homepage": "./",
"private": true,
最简单的答案是,如果您更改"homepage"
的值并将其设置为""
,或者将其实际部署到的站点主页的URL,它将直接起作用。
"homepage": "",
OR
"homepage: "mysite.com/",
这就是为什么我认为这很有效:
如果您现在使用react-scripts build
,它将创建一个文件build/index.html
,该文件将导入JS文件,例如<script src="./static/js/main.9ea6b007.chunk.js">
。
现在,当您使用react-router时,理想情况下,您希望将所有请求路由到build/index.html
。因此,您可以按如下方式构建代理服务器来服务index.html
和静态文件(使用Express.js):
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'build')));
app.use('/', (req, res) => {
res.sendFile(path.join(__dirname, 'build/index.html'));
});
app.listen(process.env.PORT || 3000, () => console.log(`Running on PORT ${process.env.PORT || 3000}`));
现在,您看到所有请求(除了静态文件的请求)都返回index.html
文件。因此,当您请求/static/js/main.9ea6b007.chunk.js
时,将返回所有JS和CSS文件。请注意,这与您的index.html
来源有何不同? src
中的index.html
尝试向./static/...
请求,而.
被解释为当前路由。
因此,假设您要访问localhost:3000/abcd
,并希望显示所需的页面。让我们看看这里发生了什么。
index.html
。index.html
尝试请求./static/...
,它转换为localhost:3000/abcd/static/...
,而您希望它是localhost:3000/static/...
。而且任何非/static
的内容都将返回相同的index.html
,因此,即使JS文件也返回相同的页面,从而导致控制台错误Uncaught SyntaxError: Unexpected token '<'
。index.html
相同。因此,homepage
中的package.json
在index.html
中用作所有静态文件的前缀,格式为<homepage>/static/...
。因此,它必须为""
,以便将请求发送到/static/...
或"mysite.com/"
,以便将请求发送到mysite.com/static/...
。
答案 2 :(得分:1)
这是一个与Apache有关的问题
确保您的Apache服务器将每个请求都重定向到index.html文件。确保.htaccess中存在以下代码
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
答案 3 :(得分:1)
对于我来说,Lili Susan V的解决方案对我来说适用于以下代码:
import { HashRouter as Router } from 'react-router-dom';
答案 4 :(得分:0)
试试这个,以这种方式定义路由:
path="/"
原因:您需要按IndexRoute
定义主路径Root的路径,并且您不需要为App组件定义单独的路由,它已经是您的{{1 }}。每当您导航到/
时,它都会呈现App
组件。
答案 5 :(得分:0)
当我在Firebase Hosting上部署React应用程序时,最初遇到了类似的问题。
我发现问题实际上是与响应路由器无关,正如接受的答案的发布者所建议的。 HashRouter会将/#/附加在我们的URL之前,无论如何看起来都不是很漂亮。
我发现问题出在我们使用的网络托管服务。我们需要指示要渲染的默认HTML文件,即 index.html 。
发生这种情况是因为我们的托管服务提供商(可能是Amazon的S3 / Apache / Google Cloud Platform(GCP)的App Engine / Firebase托管等)不知道要呈现哪个HTML文件如果给出了默认URL(https://www.link_to_your_website.com)以外的URL。例如,它将无法识别https://www.link_to_your_website.com/login。
在Firebase托管中,您需要执行以下操作:
"rewrites": [ {
"source": "**",
"destination": "/index.html"
}]
在Apache的.htaccess中,您需要执行以下操作:
FallbackResource /index.html
来源:How to redirect an error 404 to home page with .htaccess?
这些命令将告诉他们无论如何都呈现index.html,因为React-Route将使用新的React Elements动态更新HTML DOM的树,
希望遇到类似问题的人能从中受益。
答案 6 :(得分:0)
最近遇到类似的问题,我的问题有点不同,有些事情无法处理HashRouter或服务器配置...
我最初是使用render props方法来渲染这样的路由组件
<Route
path={route.path}
render={(props) => (
<route.component {...props} routes={route.routes} />
)}
/>
当我转换成这样的渲染子方法时
<Route path={route.path} key={route.path} children={<route.component />} />
有效
因此我最终的路由器设置如下所示
const routerConfig = [
{
path: '/billing',
component: ComponentA,
linkName: 'BILLING',
},
{
path: '/update-price',
component: ComponentB,
linkName: 'PRICE UPDATE',
},
]
const MainPage = () => {
return (
<Switch>
{routerConfig.map((route) => (
<RouteWithSubRoutes key={route.path} {...route} />
))}
</Switch>
)
}
function RouteWithSubRoutes(route) {
return <Route path={route.path} key={route.path} children={<route.component />} />
}
答案 7 :(得分:-1)
我面临着同样的问题,阅读了多篇文章,但找不到完美的答案,但这些文章使我对问题有了清晰的了解。因此,我以这种方式解码了问题: