在使用create-react-app创建的React项目中进行页面导航(使用react-router-dom)
尝试使用 react-router-dom(v6.16.0) 来引入页面路由的 React 页面转换方法。
即使是 SPA,也有很多从页面中受益的地方,所以我想试一试。
当我在 package.json 中设置了 homepage 时,遇到了一点问题…
通过使用 process.env.PUBLIC_URL 来解决了这个问题,所以我在这里做了一些备忘。
我使用了基于 create-react-app 创建的项目作为基础,并删除了不需要的文件。
大致上的操作如下。
-
- Reactプロジェクト作成 Win11
-
- Reactプロジェクトから不要ファイル削除(./src直下削除)
-
- Reactプロジェクトでページ遷移(react-router-dom v6.16.0使用)
react-router-dom インストール
ページのディレクトリ作成
ページ遷移の実装
ページ遷移の実装(コンポーネントにまとめる)
ページリンクのスタイル調整
最终成品可以在这里找到:
https://github.com/sueasen/my-app-react-router-dom
在 Windows 11 上创建 React 项目。
参考このページで、Node.jsのインストール方法を説明しています。
从React项目中删除不必要的文件(./src文件夹下的文件)
参考这个页面,我简单地把它分成了index.js和App.js做初始化。
在React项目中进行页面导航(使用react-router-dom v6.16.0)
安装 react-router-dom
只需要执行以下命令
npm i react-router-dom
创建页面目录
在src目录下创建一个名为pages的文件夹。
页面转换的实现
作为页面跳转的实际步骤,可以按照以下方式进行。
-
- 遷移用ページのコンポーネント作成
BrowserRouter よりページ情報定義・表示
ページ遷移のリンク追加
创建迁移页面的组件
创建三个页面(主页、第一页、第二页),在每个页面的页面下方简单显示文字。
第二页设置为接收属性(参数)。
const Home = () => {
return (
<>
<p>Home</p>
</>
);
};
export default Home;
const Page1 = () => {
return (
<>
<p>Page1</p>
</>
);
};
export default Page1;
const Page2 = (props) => {
return (
<>
<p>Page2 {props.text}</p>
</>
);
};
export default Page2;
通过BrowserRouter定义和显示页面信息
为了使用BrowserRouter在App.js中定义和显示页面信息,执行以下操作。
-
- BrowserRouter, Routes, Route を react-router-dom からインポート
-
- ページ用コンポーネントをインポート
-
- BrowserRouter の basename に process.env.PUBLIC_URL を設定
process.env.PUBLIC_URL を設定すると homepage 設定した時などパスが狂わなくなる
Route に各々の path, element(コンポーネント) を設定
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
const App = () => {
return (
<>
<h1>Hello World</h1>
<p>App.jsx</p>
{/* BrowserRouter, Routes, Route の定義、path に一致する element を表示 */}
<BrowserRouter basename={process.env.PUBLIC_URL}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/page1" element={<Page1 />} />
<Route path="/page2" element={<Page2 text="text sample" />} />
</Routes>
</BrowserRouter>
</>
);
};
export default App;
增加页面链接导航
如果添加了用于页面跳转的链接,就可以了。
在设置链接时,添加 process.env.PUBLIC_URL 到 basename 上,这样路径就不会错乱了。
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
const App = () => {
return (
<>
<h1>Hello World</h1>
<p>App.jsx</p>
{/* 以下リンクを追加 */}
<ul>
<li>
<a href={`${process.env.PUBLIC_URL}/`}>Home</a>
</li>
<li>
<a href={`${process.env.PUBLIC_URL}/page1`}>Page1</a>
</li>
<li>
<a href={`${process.env.PUBLIC_URL}/page2`}>Page2</a>
</li>
</ul>
{/* BrowserRouter, Routes, Route を定義 */}
<BrowserRouter basename={process.env.PUBLIC_URL}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/page1" element={<Page1 />} />
<Route path="/page2" element={<Page2 text="text sample" />} />
</Routes>
</BrowserRouter>
</>
);
};
export default App;
将页面转换实现(整合到组件中)
将页面转换的实现汇总到组件中
通过定义并传递与页面转换相关的信息,创建一个返回页面转换链接的BrowserRouter组件
可能有更好的方法,但通过传递定义的信息,尝试将其转化为可行的形式
创建页面传输链接的组件
在pages文件夹下创建一个名为AppRouter.js的组件,该组件返回一个页面转移链接。
import { BrowserRouter, Routes, Route } from 'react-router-dom';
// pages は [{key:key1, path:path1, element:element1}, ...] を受け取る
export const appRouter = (pages) => {
// BrowserRouter 返す処理
const router = () => {
return (
<>
<BrowserRouter basename={process.env.PUBLIC_URL}>
<Routes>
{pages.map((p) => (
<Route key={p.key} path={p.path} element={p.element} />
))}
</Routes>
</BrowserRouter>
</>
);
};
// ページ遷移リンク 返す処理
const links = () => (
<ul>
{pages.map((p) => (
<li key={p.key}>
<a href={`${process.env.PUBLIC_URL}${p.path}`}>{p.key}</a>
</li>
))}
</ul>
);
// BrowserRouter, ページ遷移リンク の定義を返す
return {
browserRouter: router(),
navbarLink: links(),
};
};
使用App.js中的AppRouer.js进行实现。
导入`pages`并将其定义为`AppRouer`的设置,然后使用`browserRouter`和`navbarLink`进行重写。
import { appRouter } from './pages/AppRouter';
import Home from './pages/Home';
import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
// ページ情報を定義して appRouter に設定
const pages = [
{ key: 'Home', path: '/', element: <Home /> },
{ key: 'Page1', path: '/page1', element: <Page1 /> },
{ key: 'Page2', path: '/page2', element: <Page2 text="text sample" /> },
];
const router = appRouter(pages);
const App = () => {
return (
<>
<h1>Hello World</h1>
<p>App.jsx</p>
{/* appRouter の navbarLink に書き換え*/}
{router.navbarLink}
{/* appRouter の browserRouter に書き換え*/}
{router.browserRouter}
</>
);
};
export default App;
只要能执行并完成页面跳转就可以了!
页面链接样式调整
给菜单链接等应用样式
App.css : 新規作成、スタイルを定義
App.js : インポート追加 App.css
AppRouter.js : タグやクラス属性を追加
body {
margin: 0;
font-family: "Futura", Helvetica, sans-serif;
}
/* Navbar & Navmenu color */
:root {
--background-navbar: rgba(55, 55, 55, 0.98);
--height-navbar: 52px;
}
.header {
background: var(--background-navbar);
position: fixed;
width: 100%;
height: var(--height-navbar);
}
/* Nav items */
.menu {
list-style: none;
position: absolute;
width: 100%;
height: auto;
top: 0;
margin-top: var(--height-navbar);
padding: 0 0 10px 0;
clear: both;
background: var(--background-navbar);
transition: 0.3192s cubic-bezier(0.04, 0.04, 0.12, 0.96) 0.1008s;
transform: scale(1, 0);
transform-origin: top;
}
/* Hamburger menu button */
.menu-btn:checked~.menu {
transform: scale(1, 1);
transform-origin: top;
transition: 0.3192s cubic-bezier(0.04, 0.04, 0.12, 0.96) 0.1008s;
}
/* Hamburger menbu text */
.menu a {
text-decoration: none;
font-weight: 500;
letter-spacing: 2px;
font-size: 16px;
text-transform: capitalize;
color: #ddd;
opacity: 0;
transition: 0.5s;
}
.menu li {
border-top: 1px solid rgb(75, 75, 75);
padding: 15px 0;
margin: 0 54px;
opacity: 0;
transition: 0.5s;
}
.menu-btn:checked~.menu a,
.menu-btn:checked~.menu li {
opacity: 1;
transition: 0.3192s cubic-bezier(0.04, 0.04, 0.12, 0.96) 0.2s;
}
.menu-btn {
display: none;
}
.menu-icon {
display: inline-block;
position: relative;
cursor: pointer;
padding: 24px 14px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.navicon {
background: #ddd;
display: block;
height: 3px;
width: 26px;
position: relative;
transition: 0.3192s cubic-bezier(0.04, 0.04, 0.12, 0.96) 0.1008s;
}
.navicon:before,
.navicon:after {
content: "";
display: block;
height: 100%;
width: 100%;
position: absolute;
background: #ddd;
transition: 0.3192s cubic-bezier(0.04, 0.04, 0.12, 0.96) 0.1008s;
}
.navicon:before {
top: 9px;
}
.navicon:after {
bottom: 9px;
}
/* Hamburger Menu Animation Start */
.menu-btn:checked~.menu-icon .navicon:before {
transform: rotate(-45deg);
}
.menu-btn:checked~.menu-icon .navicon:after {
transform: rotate(45deg);
}
.menu-btn:checked~.menu-icon:not(.steps) .navicon:before {
top: 0;
}
.menu-btn:checked~.menu-icon:not(.steps) .navicon:after {
bottom: 0;
}
.menu-btn:checked~.menu-icon .navicon {
background: rgba(0, 0, 0, 0);
transition: 0.2192s cubic-bezier(0.04, 0.04, 0.12, 0.96) 0.1008s;
}
/* Hamburger Menu Animation End */
/* Navbar Container */
.navtext-container {
width: 100%;
height: var(--height-navbar);
position: absolute;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
/* Navbar Text */
.navtext {
position: absolute;
text-transform: uppercase;
color: #ddd;
letter-spacing: 4px;
font-size: 20px;
}
main {
padding-top: var(--height-navbar);
}
import { appRouter } from './pages/AppRouter';
import Home from './pages/Home';
import Page1 from './pages/Page1';
import Page2 from './pages/Page2';
// css 追加
import './App.css';
// ページ情報を定義して appRouter に設定
const pages = [
{ key: 'Home', path: '/', element: <Home /> },
{ key: 'Page1', path: '/page1', element: <Page1 /> },
{ key: 'Page2', path: '/page2', element: <Page2 text="text sample" /> },
];
const router = appRouter(pages);
const App = () => {
return (
<>
{router.navbarLink}
{/* 位置調整で main で括る */}
<main>
<h1>Hello World</h1>
<p>App.jsx</p>
{router.browserRouter}
</main>
</>
);
};
export default App;
import { BrowserRouter, Routes, Route } from 'react-router-dom';
export const appRouter = (pages) => {
const router = () => {
return (
<>
<BrowserRouter basename={process.env.PUBLIC_URL}>
<Routes>
{pages.map((p) => (
<Route key={p.key} path={p.path} element={p.element} />
))}
</Routes>
</BrowserRouter>
</>
);
};
// タグ, クラスなど追加
const links = () => (
<header className="header">
<div className="navtext-container">
<div className="navtext">title</div>
</div>
<input type="checkbox" className="menu-btn" id="menu-btn" />
<label htmlFor="menu-btn" className="menu-icon">
<span className="navicon"></span>
</label>
<ul className="menu">
{pages.map((p) => (
<li key={p.key}>
<a href={`${process.env.PUBLIC_URL}${p.path}`}>{p.key}</a>
</li>
))}
</ul>
</header>
);
return {
browserRouter: router(),
navbarLink: links(),
};
};
如果以这种方式显示就可以了