React でのルーティング
URLハッシュ
- URL のハッシュはアンカー ポイントであり、基本的に window.location の href 属性を変更します。
- location.hash を直接割り当てて href を変更することはできますが、ページは更新されません。
<body>
<div id="app">
<a href="#/home">首页</a>
<a href="#/about">关于</a>
<div class="router-view"></div>
</div>
</body>
<script>
const routerView = document.getElementsByClassName("router-view")[0];
//监听URL的改变
window.addEventListener("hashchange",()=>{
switch(location.hash){
case "#/home":
routerView.innerHTML = "首页";
break;
case "#/about":
routerView.innerHTML = "关于";
break;
default:
routerView.innerHTML = "";
}
})
</script>
HTML5の歴史
- 履歴インターフェイスは HTML5 に新しく追加されたもので、ページを更新せずに URL を変更する 6 つのモードがあります。
方法 | 説明 |
---|---|
履歴.back() | ブラウザー履歴の前のページに移動するには、ユーザーはブラウザーの左上隅にある戻る (翻訳者注: ←) ボタンをクリックして、この方法をシミュレートできます。 |
履歴.forward() | ブラウザー履歴の次のページに移動するには、ユーザーはブラウザーの左上隅にある進む (翻訳者注: →) ボタンをクリックして、このメソッドをシミュレートできます。 |
歴史.go() | 現在のページとの相対位置に基づいて、ブラウザ履歴 (セッション レコード) からページを読み込みます。たとえば、パラメータが -1 の場合は前のページ、パラメータが 1 の場合は次のページです。 |
History.pushState() | 指定された名前と URL (このパラメーターが指定されている場合) に従ってセッション履歴スタックにデータをプッシュすると、データは DOM によって不透明に処理されます。シリアル化できる任意の JavaScript オブジェクトを指定できます。 |
History.replaceState() | 指定されたデータ、名前、および URL (指定されている場合) を使用して、履歴スタックの最新のエントリを更新します。このデータは DOM によって不透明になります。シリアル化できる任意の JavaScript オブジェクトを指定できます。 |
<body>
<div>
<div id="app">
<a href="/home">首页</a>
<a href="/about">关于</a>
<div class="router-view"></div>
</div>
</div>
<script>
const routerView = document.getElementsByClassName("router-view")[0];
const aEL = document.getElementsByTagName("a");
for (let i = 0; i < aEL.length; i++) {
aEL[i].addEventListener("click", e => {
e.preventDefault();
const href = aEL[i].getAttribute("href");
history.pushState({
}, "", href);
urlChange();
})
}
// for(let el of aEL){
// el.addEventListener("click",e => {
// e.preventDefault();
// const href = el.getAttribute("href");
// history.pushState({},"",href);
// })
// }
//执行返回操作时,依然来到urlChange
window.addEventListener("popstate",urlChange);
function urlChange() {
switch (location.pathname) {
case "/home":
routerView.innerHTML = "首页";
break;
case "/about":
routerView.innerHTML = "关于";
break;
default:
routerView.innerHTML = "";
}
}
</script>
</body>
ルーターの基本的な使い方
react-router最主要的API是给我们提供的一些组件:
-
BrowserRouter または HashRouter
1. ルーターにはパス変更の監視が含まれており、対応するパスをサブコンポーネントに渡します;
2. BrowserRouter は履歴モードを使用します;
3. HashRouter はハッシュ モードを使用します。 -
リンクと NavLink
1. リンク コンポーネントは通常、パスをジャンプするために使用され、最終的に要素としてレンダリングされます; 2.
NavLink はリンクに基づいていくつかのスタイル属性を追加します;
3. to 属性: 最も重要な属性[リンク] で、[ジャンプ先のパスを設定するには] を使用します。 -
ルート
1. ルートはパスの一致に使用されます;
2. パス属性: 一致したパスの設定に使用されます;
3. コンポーネント属性: パスの一致後にレンダリングされたコンポーネントを設定します;
4. 完全一致: 完全一致、完全一致のみ完全一致 一貫したパス対応するコンポーネントをレンダリングします。 -
NavLink コンポーネントの使用
<NavLink>是<Link>的特定版本,会在匹配上当前的url的时候给已渲染的元素添加参数
- activeStyle(object): 要素が選択されている場合、この要素にスタイルを追加します。
- activeClassName(string): 選択したスタイルを設定します。デフォルト値はアクティブです。
- strict(boolean): 正確に一致するかどうか
1. 注: コンポーネントに正確な属性を追加すると、ルートが URL と正確に一致するようになります
2. 正確な属性が追加されていない場合は、「/about」コンポーネントにも含まれますおよび「/profile」コンポーネント 「/」をレンダリングするコンポーネント
<NavLink exact to="/" activeStyle={
{
color:"blue"}}>首页</NavLink>
<NavLink to="/about" activeStyle={
{
color:"blue"}}>关于</NavLink>
<NavLink to="/profile" activeStyle={
{
color:"blue"}}>首页</NavLink>
スイッチコンポーネントの使用
- 位置によって一致した最初の要素を子としてレンダリングするか、
質問: /about パスが一致すると、/:userid も一致し、最後の NoMatch コンポーネントが常に一致します。この問題を解決するにはどうすればよいですか?
<Route exact path="/" exact component={
home} />
<Route path="/about" component={
about} />
<Route path="/profile" component={
profile} />
<Route path="/:id" component={
user} />
<Route path="/user" component={
noMatch} />
回答: 現時点では、Switch コンポーネントを使用してすべての Route コンポーネントをラップできます。
<Switch>
<Route exact path="/" exact component={
home} />
<Route path="/about" component={
about} />
<Route path="/profile" component={
profile} />
<Route path="/:id" component={
user} />
<Route path="/user" component={
noMatch} />
</Switch>
リダイレクトコンポーネントの使用
- リダイレクトはルーティングのリダイレクトに使用され、対応するパスへのジャンプを実行します。
import React, {
PureComponent } from 'react'
import {
Redirect } from 'react-router-dom';
export default class user extends PureComponent {
constructor(props){
super(props);
this.state ={
isLogin: true
}
}
render() {
return this.state.isLogin ? (
<div>
<h2>user</h2>
<h2>用户名:boge</h2>
</div>
) : <Redirect to="/login" />
}
}
配線ジャンプを手動で実現する
たとえば、共通コンポーネント (ボタン ボタン) クリックを実装してルーティング ジャンプを実行する場合は、次の 2 つの条件を満たす必要があります。
- 通常のコンポーネントは Router コンポーネント内にラップする必要があります。
- 通常のコンポーネントは withRouter の高レベル コンポーネントでラップされます。
src/App.js ファイル
import React, {
PureComponent } from 'react'
import {
withRouter} from 'react-router-dom'
class App extends PureComponent {
}
export default withRouter(App);
src/index.js ファイル
import React from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.render(
<BrowserRouter> //这里要包裹一个Router组件才能使用withRouter高阶组件
<App />
</BrowserRouter>,
document.getElementById('root')
);
動的ルーティング
パラメータを渡すには 3 つの方法があります。
- 動的ルーティングの方法。
- 検索パスパラメータ。
- Link でオブジェクトを渡すには;
動的ルーティングの概念 – ルーティング内のパスが固定されていないことを指します。
- 動的ルーティング方法
1. /detail のパスがコンポーネント詳細に対応する場合
2. パス内のルートが /detail/:id と一致する場合、/detail/123 および /detail/xyz をルートと一致させることができます。表示される
<NavLink to="/detail/abc123">详情</NavLink>
<Route path="/detail/:id" component={
detail} />
- 検索パスパラメータ
<NavLink to="/detail2?name=boge&age=20">详情2</NavLink>
- リンクでオブジェクトを渡すには
<NavLink to={
{
pathname: "/detail2",
search:"?name=abc",
state: id
}}>详情3</NavLink>
反応ルーター構成
すべてのルーティング設定を 1 か所にまとめて一元管理したい場合は、現時点では、react-router-config を使用できます。
- 糸追加反応ルーター構成
- ルート マップのリレーショナル配列を設定する
src/router/index.js ファイル
import home from '../pages/home';
import about,{
AboutHistory,AboutCulture,AboutContact,AboutJoin} from '../pages/about';
const routes = [
{
path:"/",
component:home,
exact:true
},
{
path:"/about",
component:about,
routes: [
{
path:"/about",
component: AboutHistory,
exact: true
},
{
path:"/about/culture",
component: AboutCulture,
},
{
path:"/about/contact",
component: AboutContact,
},
{
path:"/about/join",
component: AboutJoin,
}
]
}
]
export default routes;
- renderRoutes 関数を使用して構成を完了します
src/App.js ファイル
import React, {
PureComponent } from 'react';
import {
NavLink,withRouter} from 'react-router-dom';
import {
renderRoutes} from 'react-router-config';
import routes from './router';
App extends PureComponent {
render() {
const id = "abc"
return (
<div>
<NavLink exact to="/" activeClassName="link-active">首页</NavLink>
<NavLink to="/about" activeClassName="link-active">关于</NavLink>
<NavLink to="/profile" activeClassName="link-active">我的</NavLink>
<NavLink to="/user" activeClassName="link-active">用户</NavLink>
<NavLink to={
`/detail/${
id}`} activeClassName="link-active">详情</NavLink>
<NavLink to={
{
pathname: "/detail2",
search:"?name=abc",
state: id
}} activeClassName="link-active">详情3</NavLink>
<button onClick={
e => this.ToProduct()}>商品</button>
{
renderRoutes(routes)}
</div>
)
}
ToProduct(){
this.props.history.push("/product");
}
}
export default withRouter(App);