簡體   English   中英

構建應用程序后反應路由器不起作用

[英]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);
}

package.json

  {
  "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.htmlsrc嘗試從./static/...請求,而. 被解釋為當前路線。

因此,假設您要訪問localhost:3000/abcd期望顯示您想要的頁面。 讓我們來看看這里發生了什么。

  • 您將按預期獲得index.html
  • index.html嘗試請求./static/... ,它轉換為localhost:3000/abcd/static/... ,而您希望它是localhost:3000/static/... 任何不是/static東西都會返回相同的index.html ,所以即使是 JS 文件也返回相同的頁面,導致控制台錯誤Uncaught SyntaxError: Unexpected token '<'
  • 如果您轉到瀏覽器 Devtools 並查看源代碼,您的所有 JS 和 CSS 文件都將具有與index.html相同的內容。

因此,您的package.jsonhomepageindex.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

我遇到了同樣的問題並閱讀了多篇文章,但找不到完美的答案,但這些文章讓我對這個問題有了清晰的了解。 所以,我以這種方式解碼了我的問題:

  1. React 是一個單頁應用程序框架
  2. 在加載網頁時加載 index.html
  3. 從索引中,我們加載與 URL 匹配的 [router]react-router-dom。
  4. 一切都在本地主機中完美運行,但在我們構建應用程序時無法在生產中運行。
  5. 在此之前沒有任何問題,因此這是我們使用的完整托管服務。
  6. 就我而言,我使用了 firebase 托管,並將所有內容重定向到 build/index.html
  7. 問題解決了!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM