[英]React router not working after building the app
我是新來的反應和 react-router。 該應用程序是使用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"
}
}
這是一個與服務器相關的問題
對於 Apache 服務器:
確保您的 Apache 服務器將每個請求重定向到 index.html 文件。 確保以下代碼存在於 .htaccess 中
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
在使用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>
這暫時解決了這個問題。 希望對遇到類似問題的其他人有所幫助。
最好的方法是使用公共 URL,它將被部署為Router
組件中的basename
prop。 它也可能是PUBLIC_URL=myproject
類的東西,它會假設應用程序在https://<domain-name>/myproject/index.html
。
<Router basename={process.env.PUBLIC_URL}>
...
</Router>
首先,這不是 React Router 的問題。 請注意,在您的package.json
,您有:
"homepage": "./",
"private": true,
簡短的回答是,如果您更改"homepage"
的值並將其"homepage"
""
或實際部署它的站點的主頁的 URL,它將直接工作。
"homepage": "",
或者
"homepage": "mysite.com/",
這就是我認為有效的原因,詳細說明:
如果你現在使用react-scripts build
,它會創建一個文件 - build/index.html
,它導入像<script src="./static/js/main.9ea6b007.chunk.js">
這樣的 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
源中的內容有何不同? index.html
的src
嘗試從./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
相同的內容。 因此,您的package.json
的homepage
在index.html
用作所有靜態文件的前綴,格式為<homepage>/static/...
。 因此它需要是""
以便請求發送到/static/...
或"mysite.com/"
,以便請求發送到mysite.com/static/...
。
當我在 Firebase Hosting 上部署我的 React 應用程序時,我最初遇到了類似的問題。
事實證明,正如已接受答案的發布者所建議的那樣,問題實際上不在於反應路由器。 HashRouter 會在我們的 URL 前面附加 /#/,不管怎樣,這看起來不是很漂亮。
我發現問題出在我們使用的網絡托管服務上。 我們需要指明我們想要呈現的默認 HTML 文件,即index.html 。
發生這種情況是因為我們的托管服務提供商(無論是 Amazon 的 S3 / Apache / Google Cloud Platform (GCP) 的 App Engine / Firebase Hosting 等)不知道如果 URL 不是默認 URL ( https ://www.link_to_your_website.com ) 已給出。 例如,它將無法識別https://www.link_to_your_website.com/login 。
在 Firebase 托管中,您需要執行以下操作:
"rewrites": [ {
"source": "**",
"destination": "/index.html"
}]
在 Apache 的 .htaccess 中,您需要執行以下操作:
FallbackResource /index.html
來源: 如何使用 .htaccess 將錯誤 404 重定向到主頁?
這些命令會告訴他們無論如何都要渲染 index.html,因為 React-Route 將使用新的 React 元素動態更新 HTML DOM 的樹。
希望那些遇到過類似問題的人會發現這很有幫助。
對我來說,Lili Susan V 的解決方案使用以下代碼對我有用:
import { HashRouter as Router } from 'react-router-dom';
試試這個,以這種方式定義路由:
<Router history={browserHistory}>
<Route path="/" component={Root}>
<IndexRoute component={App} />
<Route path="/sna/:country" component={SNA} />
<Route path="*" component={FourOFour}/>
</Route>
</Router>
原因:您需要通過path="/"
定義主路由 Root 的path="/"
,並且您不需要為 App 組件定義單獨的路由,它已經是您的IndexRoute
。 每當您導航到/
,它將呈現App
組件。
最近遇到了類似的問題,我的問題有點不同,而且與 HashRouter 或服務器配置無關...
我最初使用渲染道具方法來渲染這樣的路由組件
<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 />} />
}
如果未為 Apache 啟用重寫 mod,也會出現此問題。 您可以通過執行來啟用它:
sudo a2enmod rewrite
我嘗試了幾種方法並為我工作(對於 static 構建在根文件夾或子文件夾中)
我已經在子文件夾中部署了我的應用程序,我遵循了這個配置
在 Reactjs 側
我的依賴
package.json
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-router-dom": "^5.2.0",
主頁鍵
"homepage": "/SUBFOLDER",
在index.js
中用於路由
<Router basename={"SUBFOLDER"}>
在 Apache 側
cd /etc/apache2/sites-available/
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName DOMAINNAME
DocumentRoot /var/www/html/DOMAINNAME/
<Directory /var/www/html/DOMAINNAME/SUBDIRECTORY/>
#Options -Indexes +FollowSymLinks
#AllowOverride All
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
</Directory>
進行必要的更改后,檢查配置並重新啟動 apache
sudo apache2ctl configtest
sudo systemctl restart apache2
我遇到了同樣的問題並閱讀了多篇文章,但找不到完美的答案,但這些文章讓我對這個問題有了清晰的了解。 所以,我以這種方式解碼了我的問題:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.