在網路上查找相關文章的時候,發現很多用法已經淘汰了,所以就自己整理這篇來當作筆記。
現在react-router-dom v6 版本改了很多,例如:
以下將重大差異的部份個別列出。
之前的定義: 在每一個Route判斷到網址的路徑相符,要渲染該組件時都會將物件match給傳進該組件中。
也因為以上特性,所以早期很多人寫法都是直接從match取得參數:
const NotePage = ({match}) => {
let noteId = match.params.id
}
另外在DOM v6之前也有人使用match取得path:
import React from "react"
import { Route, Link } from "react-router-dom"
class About extends React.Component {
render() {
//在Route將組件渲染時,會傳入match物件,在這裡把它印出來
console.log(this.props.match)
return (
<div>
<h2>關於我們選單</h2>
<ul>
{/*url是match的屬性之一,會回傳網址列的路徑*/}
<li><Link to={`${this.props.match**.url**}`}>理念介紹</Link></li>
<li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
</ul>
{/*path也是match的屬性之一,會回傳透過哪個Route進入的path屬性*/}
<Route exact path={`${this.props.match**.path**}`} component={Introd} />
<Route path={`${this.props.match.path}/his`} component={His} />
</div>
)
}
}
取得參數部分,由useParams取代,如下:
const NotePage = () => {
let {id} = useParams();
}
如果要取得現在的URL,則變成是要用useLocation():
const location = useLocation();
console.log(location.pathname);
Here are the properties it returns:
在DOM v5版本中我們可以使用Redirect Component強制轉導,
概念為:
class About extends React.Component {
render() {
return (
<div>
<Switch>
<Route exact path={`${this.props.match.path}`} component={Introd} />
<Route path={`${this.props.match.path}/his`} component={His} />
//...
<Redirect from={`${this.props.match.path}/story`} to={`${this.props.match.url}/his`} />
</Switch>
</div>
)
}
}
from意思是當目前的Link連結到${this.props.match.path}/story這個路徑的時候,Redirect會將網址重新轉到${this.props.match.url}/his上。
Redirect的to屬性具體如下:
<Redirect from={`${this.props.match.path}/story`}
to={{pathname:`${this.props.match.url}/his`
,search: "?hey=UCCU"
,state:{name:'Referrer'}}} />
React 是 React Router v6 中新引入的組件,其作用與已棄用的 組件相同。
我們可以使用導航組件聲明重定向,如下所示:
<Navigate to="/somewhere/else" />
鑑於我們希望在用戶訪問我們應用程序上的無效 URL 時將用戶重定向到 home 組件,我們可以這樣編寫導航代碼:
<Routes>
<Route path='/' element={<h1>Home Page Component</h1>} />
<Route path='/login' element={<h1>Login Page Component</h1>} />
// New line
<Route path='*' element={**<Navigate to='/' />**} />
</Routes>
useHistory 鉤子是React Router Dom v5中的一個函數,它使我們能夠訪問瀏覽器History Stack實例。
useHistory 可用於從當前位置 導航到新位置 或 返回到特定位置。
import { useHistory } from "react-router-dom";
import "./App.css";
function App() {
const history = useHistory();
const handleGoBack = () => {
history.goBack();
};
return (
<>
<button onClick={handleGoBack}>Go Back</button>
</>
);
}
export default App;
從上面的代碼中,我們使用 useHistory hook中的 goBack() 方法來建立 回上一頁按鈕功能。
我們還可以使用 useHistory Hook重定向到新路徑,如下所示:
import { useHistory } from "react-router-dom";
import "./App.css";
function App() {
const history = useHistory();
const handleGoHome = () => {
history.push("/home"); // New line
};
return (
<>
<button onClick={handleGoHome}>Go Back</button>
</>
);
}
export default App;
useHistory 在 React Router v6 中也被棄用,取而代之的是 useNavigate。
useNavigate 允許我們在函數內以編程方式導航路徑,它採用與 組件相同的props,並且與 useHistory 具有相同的目的。
例如我們使用useNavigate()模擬用戶登錄時重定向到登錄頁面:
import { useEffect, useState } from "react";
import { Navigate, Route, Routes, useNavigate } from "react-router-dom";
import "./App.css";
function App() {
const navigate = useNavigate();
const [isLoggedIn, setisLoggedIn] = useState(false);
useEffect(() => {
// Checking if user is not loggedIn
if (!isLoggedIn) {
navigate("/");
} else {
navigate("/login");
}
}, [navigate, isLoggedIn]);
return (
<>
<Routes>
<Route path='/' element={<h1>Home Page Component</h1>} />
<Route path='/login' element={<h1>Login Page Component</h1>} />
<Route path='*' element={<Navigate to='/' />} />
</Routes>
{/* New line */}
{isLoggedIn || (
<button onClick={() => setisLoggedIn(true)}>Log me in</button>
)}
</>
);
}
export default App;
如上範例,官方傾向於建議在useEffect()中使用useNavigate。
另外,由於能夠操作瀏覽器History Stack,因此也能做到重定向到上一頁:
import { useNavigate } from "react-router-dom";
import "./App.css";
function App() {
const navigate = useNavigate();
const handleGoBack = () => {
navigate(-1); // new line
};
return (
<>
<button onClick={handleGoBack}>Go Back</button>
</>
);
}
export default App;
Pass props in Link react-router
上面這篇討論很多解法
但我自己試成功是使用官網範例:
https://reactrouter.com/en/6.8.0/components/link#state
The state
property can be used to set a stateful value for the new location which is stored inside history state. This value can subsequently be accessed via useLocation()
.
<Link to="new-path" state={{ some: "value" }} />
You can access this state value while on the "new-path" route:
let { state } = useLocation();
In react-router-dom
v6 there is no longer a use case/allowance for custom route components. Only Route
(or Fragment
) components can be children of the Routes
component. The layout components are rendered on a Route
component's element
prop and they can render children components or Outlets
if they are wrapping nested Route
components.
Given a layout components rendering a children
prop *:
const NoNavbarLayout = ({ children }) => (
<div className="login-layout">
<p>No navbar</p>
{children}
</div>
);
NavbarLayout
component is similarThe routes would look as such:
<Routes>
<Route
path="/bossHome"
element={(
<NoNavbarLayout>
<BossHomePage />
</NoNavbarLayout>
)}
/>
<Route
path="/home"
element={(
<NavbarLayout>
<Home />
</NavbarLayout>
)}
/>
</Routes>
參考資料:
臨時找不到原本參考的那篇,找到了再補上來