ReactRouterの実装
説明する
ブラウザ履歴
位置 / { try_files $uri $uri/ /index.html; } ハッシュ履歴
記憶の履歴
定数履歴 = createMemoryHistory(場所); 成し遂げる非常にシンプルな <!-- ブラウザ履歴 --> <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <title>ルーター</title> </head> <本文> <ul> <li><a href="/home" rel="external nofollow" >ホーム</a></li> <li><a href="/about" rel="external nofollow" >について</a></li> <div id="ルートビュー"></div> </ul> </本文> <スクリプト> 関数ルーター() { this.routeView = null; // コンポーネントホストビューコンテナ this.routes = Object.create(null); // 定義されたルート } // ルートマッチングイベントをバインドする Router.prototype.route = function (path, callback) { this.routes[path] = () => this.routeView.innerHTML = callback() || ""; }; // InitializeRouter.prototype.init = function(root, rootView) { this.routeView = rootView; //ビューコンテナを指定する this.refresh(); //ビューを初期化して更新する root.addEventListener("click", (e) => { //ルートへのイベント委譲 if (e.target.nodeName === "A") { e.preventDefault(); history.pushState(null, "", e.target.getAttribute("href")); this.refresh(); // ビューを更新するためのトリガー} }) // ユーザーの「戻る」と「進む」のクリックをリッスンします // pushState と replaceState は popstate イベントをトリガーしません window.addEventListener("popstate", this.refresh.bind(this), false); }; // ビューを更新するRouter.prototype.refresh = function () { path = location.pathname とします。 console.log("更新", パス); this.routes[path] の if(this.routes[path]()); それ以外の場合は this.routeView.innerHTML = ""; }; window.Router = 新しい Router(); Router.route("/home", 関数() { 「ホーム」を返します。 }); Router.route("/about", 関数() { 「about」を返します。 }); Router.init(ドキュメント、document.getElementById("routeView")); </スクリプト> </html> <!-- ハッシュ履歴 --> <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <title>ルーター</title> </head> <本文> <ul> <li><a href="#/home" rel="external nofollow" >ホーム</a></li> <li><a href="#/about" rel="external nofollow" >について</a></li> <div id="ルートビュー"></div> </ul> </本文> <スクリプト> 関数ルーター() { this.routeView = null; // コンポーネントホストビューコンテナ this.routes = Object.create(null); // 定義されたルート } // ルートマッチングイベントをバインドする Router.prototype.route = function (path, callback) { this.routes[path] = () => this.routeView.innerHTML = callback() || ""; }; // InitializeRouter.prototype.init = function(root, rootView) { this.routeView = rootView; // ビュー コンテナーを指定します this.refresh(); // 初期化トリガー // 更新するために hashchange イベントをリッスンします window.addEventListener("hashchange", this.refresh.bind(this), false); }; // ビューを更新するRouter.prototype.refresh = function () { ハッシュ = location.hash; console.log("更新", ハッシュ); this.routes[ハッシュ]を返し、this.routes[ハッシュ]を返します。 それ以外の場合は this.routeView.innerHTML = ""; }; window.Router = 新しい Router(); Router.route("#/home", 関数() { 「ホーム」を返します。 }); Router.route("#/about", 関数() { 「about」を返します。 }); Router.init(ドキュメント、document.getElementById("routeView")); </スクリプト> </html> 分析する
// packages\react-router-dom\modules\HashRouter.js 10行目 BrowserRouterクラスはReact.Componentを拡張します。 履歴 = createHistory(this.props); 与える() { <Router history={this.history} children={this.props.children} /> を返します。 } } 次に、 // 行 packages\react-router\modules\Router.js 行 10 クラス Router は React.Component を拡張します { 静的computeRootMatch(パス名) { 戻り値: { パス: "/", url: "/", パラメータ: {}, isExact: パス名 === "/" }; } コンストラクタ(props) { スーパー(小道具); この状態 = { 場所: props.history.location }; // これはちょっとしたハックです。位置情報を聞き始める必要があります // <Redirect> がある場合に備えて、コンストラクタ内で変更します // 初期レンダリング時に。存在する場合は、置き換え/プッシュされます // それらはマウントされ、cDMは親よりも先に子で発火するので、 // <Router> がマウントされる前に新しい場所を取得します。 this._isMounted = false; this._pendingLocation = null; 静的コンテキストの場合 this.unlisten = props.history.listen(location => { if (this._isMounted) { this.setState({ location }); } それ以外 { this._pendingLocation = 場所; } }); } } コンポーネントマウント() { this._isMounted = true; if (this._pendingLocation) { this.setState({ location: this._pendingLocation }); } } コンポーネントのマウントを解除します(){ this.unlisten() は、次の例のように機能します。 } 与える() { 戻る ( <ルーターコンテキスト.プロバイダー children = {this.props.children || null} 値={{ 履歴: this.props.history、 場所: this.state.location、 一致: Router.computeRootMatch(this.state.location.pathname)、 静的コンテキスト: this.props.staticContext }} /> ); } } これを使用するときは、 // \packages\react-router\modules\Route.js 17行目 クラス Route は React.Component を拡張します { 与える() { 戻る ( <ルーターコンテキスト.コンシューマー> {コンテキスト => { invariant(context, "<Router> の外部では <Route> を使用しないでください"); const location = this.props.location || context.location; 定数マッチ = this.props.computedMatch ? this.props.computedMatch // <Switch> はすでに一致を計算しています : this.props.path ? matchPath(location.pathname, this.props) : コンテキストに一致します。 const props = { ...コンテキスト、場所、一致 }; let { children, component, render } = this.props; // Preactは空の配列を子として使用します // デフォルトなので、その場合は null を使用します。 Array.isArray(children) && children.length === 0 の場合 { 子 = null; } if (typeof children === "function") { 子供 = 子供(プロパティ); // ... } 戻る ( <RouterContext.Provider 値 = {props}> {子供 && !isEmptyChildren(子供) ? 子供たち : props.match ? 成分 React.createElement(コンポーネント、プロパティ) : 与える ? レンダリング(props) : ヌル : ヌル} </ルーターコンテキスト.プロバイダー> ); }} </ルーターコンテキスト.コンシューマー> ); } } 実際、おそらく最も多く書くタグは // packages\react-router-dom\modules\Link.js 14行目 クラスLinkはReact.Componentを拡張します。 handleClick(イベント、履歴) { this.props.onClick の場合、 this.props.onClick(イベント); もし ( !event.defaultPrevented && // onClick はデフォルトで禁止 event.button === 0 && // 左クリック以外はすべて無視 (!this.props.target || this.props.target === "_self") && // ブラウザに "target=_blank" などを処理させます。 !isModifiedEvent(event) // 修飾キーによるクリックを無視する ){ イベントをデフォルトにしない(); const メソッド = this.props.replace ? history.replace : history.push; メソッド(this.props.to); } } 与える() { const { innerRef, replace, to, ...rest } = this.props; // eslint-disable-line no-unused-vars 戻る ( <ルーターコンテキスト.コンシューマー> {コンテキスト => { invariant(context, "<Link> を <Router> の外部で使用しないでください"); 定数場所 = typeof を === "string" にする ? createLocation(to, null, null, context.location) : に; const href = location ? context.history.createHref(location): ""; 戻る ( <a {...休む} onClick={イベント => this.handleClick(イベント、コンテキスト.履歴)} href={href} ref={内部参照} /> ); }} </ルーターコンテキスト.コンシューマー> ); } } 毎日の質問 https://github.com/WindrunnerMax/EveryDay 参照する https://zhuanlan.zhihu.com/p/44548552 https://github.com/fi3ework/blog/issues/21 https://juejin.cn/post/6844903661672333326 https://juejin.cn/post/6844904094772002823 https://juejin.cn/post/6844903878568181768 https://segmentfault.com/a/1190000014294604 https://github.com/youngwind/blog/issues/109 http://react-guide.github.io/react-router-cn/docs/guides/basics/Histories.html ReactRouterの実装方法については以上です。ReactRouterの実装方法については、123WORDPRESS.COMの過去記事を検索するか、引き続き以下の関連記事をご覧ください。今後とも123WORDPRESS.COMをよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Linux での MySQL 5.7.16 無料インストール バージョンのグラフィック チュートリアル
>>: Dockerをクリーンアンインストールする方法の詳細な説明
Docker デーモンは、 HTTP_PROXY 、 HTTPS_PROXY 、およびNO_PRO...
絶対位置決め方式: (1)親要素を相対配置に設定します。親要素の高さを指定しない場合は、左の子要素の...
例:本日、前回のオフィスコラボレーションプラットフォーム実験の続きをしていたところ、仮想マシンは以前...
目次1. 関数の抽出2. 重複した条件付きスニペットを結合する3. 条件分岐文を関数に抽出する4. ...
macにbrewを使ってphp56をインストールしたところ、 opensslがバージョン1.1だった...
div がネストされているときに margin が機能しない問題の解決策を次に示します。さて、マージ...
MySQLはインストール版と無料インストール版に分かれていますインストール版の拡張子はmsi、無料イ...
1. イベント委任とは何ですか?イベント委譲: イベントバブリングの特性を利用して、子要素に登録すべ...
ビジネス ソーシャル ネットワーキング サイト LinkedIn は最近、ナビゲーション バーとユー...
序文最近mysql /usr/local/mysql/bin/mysql -uroot -pパスワー...
初めてこのエッセイを使ったとき、私はかなりぎこちなく感じましたhtmlファイルコードをコピーコードは...
# Windows および Linux 上の Redis のインストール デーモン構成Redis の...
オリジナル: http://developer.yahoo.com/performance/rule...
今日、私は公開用の動的なウィンドウ スタイルを設計しましたが、マウスで入力をクリックしたときにブラウ...
目次1. 二重連結リストとは何か2. 双方向リンクリストのカプセル化3. 双方向リンクリストの一般的...