---
# System prepended metadata

title: React Router v6

---

# React Router v6

:::success
:bookmark: 書籤
[TOC]
:::

[React Router Docs](https://reactrouter.com/docs/en/v6)

## Configuring Routes

跟前幾個版本差不多，在用Router的時候必須要先引入BroswerRouter來包住整個component。

***App.js***
```javascript=
import Home from "./components/Home";
import About from "./components/About";
import {BrowserRouter as Router,Routes,Route} from "react-router-dom";

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Router>
  );
}

export default App;
```

==Routes==：跟前版本的Switch的功用差不多，在Routes裡面的component都必須定義Route，不然會報錯。

==Route==：之前的使用方法是在Route上使用"component"屬性，現在改為element屬性，path的設定一樣。



## Link

如果要到Route定義的path，則可以使用Link Component，使用的方法也非常簡單，只要在Link加上to屬性指向到path就好。

***App.js***
```javascript=
import Home from "./components/Home";
import About from "./components/About";
import {BrowserRouter as Router,Routes,Route,Link} from "react-router-dom";

function App() {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link>|<Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Router>
  );
}

export default App;
```

## exact

之前的版本在定義Route的時候會發生一個情況，假如網頁的url是localhost:3000/about，那假如我在Router的定義如下，則會連同 "/" 一起匹配到，所以都會在 path 是 "/" 的加上exact，意思就是嚴格匹配，而在v6已經內建嚴格匹配了，所以不需要特別做設定。

***舊版本(v5)***
```javascript=
<Router>
    <Route path={"/"} exact component={Home} />
    <Route path={"/about"} component={About} />
</Router>
```

## NavLink
v5版本的activeClassName已經被移除了，最新版的className會自帶isActive的參數，所以直接用該參數來判斷是否active就好。

```javascript=
<NavLink className={(navData) => (navData.isActive ? "active" : "")}to="/about">
    About
</NavLink>
```


## useNavigate
取代了v5的useHistory，使用useNavigate可以很輕鬆的跳轉到其他Route path，當然，也可以使用Link Component，但就不能在function裡面去做使用。

在舊版的useHistory當我們網頁需要
回到上一頁或下一頁時會使用history.goBack()或history.goForward()

而在新版的navigate可以直接使用數字來代替

***About.js***
```javascript=
import React from "react";
import { useNavigate } from "react-router";

const About = () => {
  const navigate = useNavigate();
  return (
    <div>
      <h1>ABOUT PAGE</h1>
      <button onClick={() => navigate("/")}>Go To Home Page</button>
      <button onClick={() => navigate(1)}>1 step forward</button>      
      <button onClick={() => navigate(-1)}>1 step back</button>
    </div>
  );
};

export default About;
```



## useParams

假使我們在一個頁面需要透過url的參數來取得資料，
例如：localhost:3000/profile/wei 、 localhost:3000/profile/yun

我們想要取得url後面的wei跟yun，這時候可以透過useParams來幫助我們，但在Route的部分也要設定。

***App.js***
```javascript=
import "./App.css";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import Profile from "./components/Profile";
function App() {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link>|<Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/profile/:name" element={<Profile />} /> //加上 /:name
      </Routes>
    </Router>
  );
}

export default App;
```

***Profile.js***
```javascript=
import React from "react";
import { useParams } from "react-router";

const Profile = () => {
  const { name } = useParams(); //要跟Route設定的參數名稱一樣
  return (
    <div>
      <h1>PROFILE PAGE</h1>
      <h2>Hello {name}</h2>
    </div>
  );
};

export default Profile;
```

現在在url要是輸入 localhost:3000/profile/wei 會看到以下畫面

![](https://i.imgur.com/QhSSIlx.png)

## useSearchParams
在網址如果有帶一些參數，則可以使用useSearchParams來取得該參數的值。

假設網址是：localhost:3000/profile/wei?sortby=id

```javascript=
import React from "react";
import { useParams } from "react-router";
import { useSearchParams } from "react-router-dom";

const Profile = () => {
  const { name } = useParams();
  let [searchParams] = useSearchParams();
  console.log(searchParams.get("sortby")); //output : id
  return (
    <div>
      <h1>PROFILE PAGE</h1>
      <h2>Hello {name}</h2>
    </div>
  );
};

export default Profile;

```

假設網址是：localhost:3000/profile/wei?test=1&test=2

要是參數有兩個同名稱但不同值的話，可以使用getAll。

```javascript=
import React from "react";
import { useParams } from "react-router";
import { useSearchParams } from "react-router-dom";

const Profile = () => {
  const { name } = useParams();
  let [searchParams] = useSearchParams();
  console.log(searchParams.getAll("test")); //output : ["1","2"]
  return (
    <div>
      <h1>PROFILE PAGE</h1>
      <h2>Hello {name}</h2>
    </div>
  );
};

export default Profile;
```

## useRoutes

## 404 頁面

假設今天在Routes底下匹配不到path，會出現空白頁面，這時候我們可以自訂Error Component，當匹配不到時就會跳到該頁面。

***App.js***
```javascript=
import Home from "./components/Home";
import About from "./components/About";
import Error from "./components/Error";
import {BrowserRouter as Router,Routes,Route} from "react-router-dom";

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="*" element={<Error />} />
      </Routes>
    </Router>
  );
}

export default App;
```

在path的地方加上"\*"，意思就是Routes底下匹配不到的時候才會去匹配該path，這邊要注意的是**path="\*"的Route必須放在最底下，因為Routes匹配是有優先順序的。**


