検索
ホームページウェブフロントエンドH5 チュートリアルReact Router のコア履歴ライブラリの詳細な分析

この記事では React Router のコア履歴ライブラリの詳細な分析を紹介します。必要な方は参考にしていただければ幸いです。

前書き

ルーティング管理には、React Router がほぼ唯一の選択肢です。 React Router は 4 回のメジャー バージョン アップデートを経て、その機能はますます豊富になってきましたが、どのように変化しても、その中心となる履歴ライブラリへの依存は変わりません。 github に 4,000 以上のスターがあるこのライブラリがどのような機能を提供するかを見てみましょう。

HTML5 履歴オブジェクト

履歴ライブラリについて話すとき、この言葉に少し馴染みがあると思いませんか?はい、同じ名前の新しい履歴オブジェクトも HTML5 仕様に追加されました。この履歴オブジェクトがどのような問題を解決するために使用されるかを見てみましょう。

jQuery がフロントエンドを支配していた時代、ajax リクエストを介して更新せずにページを更新することは、当時非常に人気のあるページ処理方法であり、その時点で SPA のプロトタイプが進化しました。更新後も正しいページ要素が表示できるようにページへの変更をマークするには、通常、URL のハッシュ値が変更されてページを一意に特定できます。しかし、これは別の問題を引き起こします。ユーザーはページを切り替えるために「進む」/「戻る」を使用することができません。

この問題を解決するために、history オブジェクトが登場しました。ページの URL またはハッシュが変更されると、ブラウザは新しい URL を履歴オブジェクトに自動的にプッシュします。状態配列は、URL の変更を記録するために履歴オブジェクト内に維持されます。ブラウザが進む/戻る操作を実行すると、実際には履歴オブジェクトの対応するメソッド (forward/back) を呼び出し、対応する状態を取り出し、ページを切り替えます。 。 forward/back),取出对应的state,从而进行页面的切换。

除了操作url,history对象还提供2个不用通过操作url也能更新内部state的方法,分别是pushStatereplaceState。还能将额外的数据存到state中,然后在onpopstate事件中再通过event.state取出来。如果希望对history对象作更深入的理解,可以参考 这里,和这里。

history库与HTML5 history对象的关系

我们再回过头来看history库。它本质上做了以下4件事情:

  1. 借鉴HTML5 history对象的理念,在其基础上又扩展了一些功能

  2. 提供3种类型的history:browserHistory,hashHistory,memoryHistory,并保持统一的api

  3. 支持发布/订阅功能,当history发生改变的时候,可以自动触发订阅的函数

  4. 提供跳转拦截、跳转确认和basename等实用功能

再对比一些两者api的异同。以下是history库的:

const history = {
    length,        // 属性,history中记录的state的数量
    action,        // 属性,当前导航的action类型
    location,      // 属性,location对象,封装了pathname、search和hash等属性
    push,          // 方法,导航到新的路由,并记录在history中
    replace,       // 方法,替换掉当前记录在history中的路由信息
    go,            // 方法,前进或后退n个记录
    goBack,        // 方法,后退
    goForward,     // 方法,前进
    canGo,         // 方法,是否能前进或后退n个记录
    block,         // 方法,跳转前让用户确定是否要跳转
    listen         // 方法,订阅history变更事件
  };

以下是HTML5 history对象的:

const history = {
    length,         // 属性,history中记录的state的数量
    state,          // 属性,pushState和replaceState时传入的对象
    back,           // 方法,后退
    forward,        // 方法,前进
    go,             // 方法,前进或后退n个记录
    pushState,      // 方法,导航到新的路由,并记录在history中
    replaceState    // 方法,替换掉当前记录在history中的路由信息
}

// 订阅history变更事件
window.onpopstate = function (event) {
    ...
}

从对比中可以看出,两者的关系是非常密切的,history库可以说是history对象的超集,是功能更强大的history对象。

createHashHistory源码分析

下面,我们以三种history类型中的一种,hashHistory为例,来分析下history的源码,看看它都干了些什么。先看下它是怎么处理hash变更的。

// 构造hashHistory对象
const createHashHistory = (props = {}) => {
    ...
    const globalHistory = window.history;    // 引用HTML5 history对象
    ...
    // transitionManager负责控制是否进行跳转,以及跳转后要通知到的订阅者,后面会详细讨论
    const transitionManager = createTransitionManager();
    ...
    // 注册history变更回调的订阅者
    const listen = listener => {
        const unlisten = transitionManager.appendListener(listener);
        checkDOMListeners(1);

        return () => {
            checkDOMListeners(-1);
            unlisten();
        };
    };
    
    // 监听hashchange事件
    const checkDOMListeners = delta => {
        listenerCount += delta;

        if (listenerCount === 1) {
            window.addEventListener(HashChangeEvent, handleHashChange);
        } else if (listenerCount === 0) {
            window.removeEventListener(HashChangeEvent, handleHashChange);
        }
    };
    
    // hashchange事件回调
    const handleHashChange = () => {
        ...
        // 构造内部使用的location对象,包含pathname、search和hash等属性
        const location = getDOMLocation();    
        ...
        handlePop(location);
    };
    
    // 处理hash变更逻辑
    const handlePop = location => {
        ...
        const action = "POP";
        // 给用户展示确认跳转的信息(如果有的话),确认后通知订阅者。如果用户取消跳转,则回退到之前状态
        transitionManager.confirmTransitionTo(location, action, getUserConfirmation, ok => {
            if (ok) {
                setState({action, location});    // 确认后通知订阅者
            } else {
                revertPop(location);             // 取消则回退到之前状态
            }
        });
    };
    
    // 更新action,location和length属性,并通知订阅者
    const setState = nextState => {
        Object.assign(history, nextState);

        history.length = globalHistory.length;

        transitionManager.notifyListeners(history.location, history.action);
    };
    ...
}

以上就是处理被动的hash变更的逻辑,一句话概括就是:订阅hash变更事件,判断是否确实要变更,如需变更则更新自己的属性,通知订阅者,不需变更则回退到之前的状态。

下面再看下transitionManager做了什么,重点看发布/订阅相关内容,忽略用户确认跳转相关内容。

const createTransitionManager = () => {
    ...
    // 内部维护的订阅者列表
    let listeners = [];

    // 注册订阅者
    const appendListener = fn => {
        let isActive = true;

        const listener = (...args) => {
            if (isActive) fn(...args);
        };

        listeners.push(listener);

        return () => {
            isActive = false;
            listeners = listeners.filter(item => item !== listener);
        };
    };

    //通知订阅者
    const notifyListeners = (...args) => {
        listeners.forEach(listener => listener(...args));
    };
    ...
}

这里的代码一目了然,就是维护一个订阅者列表,当hash变更的时候通知到相关的函数。

以上是hash改变的时候被动更新相关的内容,下面再看下主动更新相关的代码,以push为例,replace大同小异。

const push = (path, state) => {
    ...
    const action = "PUSH";
    const location = createLocation(path, undefined, undefined, history.location);

    transitionManager.confirmTransitionTo(location, action, getUserConfirmation, ok => {
        if (!ok)     // 如果取消,则不跳转
            return;
        ...
        pushHashPath(encodedPath);        // 用新的hash替换到url当中
        ...
        setState({action, location});     // 更新action,location和length属性,并通知订阅者

    });
};

// 用新的hash替换到url当中
const pushHashPath = path => (window.location.hash = path);

在浏览器进行前进后退操作时,history库实际上是通过操作HTML5 history对象实现的。

const globalHistory = window.history;

const go = n => {
    ...
    globalHistory.go(n);
};

const goBack = () => go(-1);

const goForward = () => go(1);

当调用window.history.go

URL の操作に加えて、履歴オブジェクトには、URL を操作せずに内部状態を更新するための 2 つのメソッド、つまり pushStatereplaceState も提供されます。追加データを状態に保存し、onpopstate イベントの event.state を通じて取得することもできます。履歴オブジェクトをより深く理解したい場合は、こことここを参照してください。

履歴ライブラリと HTML5 履歴オブジェクトの関係

履歴ライブラリに戻って見てみましょう。基本的に次の 4 つのことを行います:

  1. HTML5 履歴オブジェクトの概念を利用し、それに基づいていくつかの機能を拡張します

  2. 3 種類の履歴を提供します:browserHistory、hashHistory、memoryHistory を提供し、統一性を維持します API

  3. はパブリッシュ/サブスクライブ機能をサポートしており、履歴が変更されると、サブスクリプション機能が自動的にトリガーされます

  4. ジャンプインターセプト、ジャンプ確認、ベースネームなどの実用的な機能を提供します

2つの類似点のいくつかを比較してみましょう。 API の違いについても説明します。以下は履歴ライブラリです:

rrreee

以下は HTML5 履歴オブジェクトです: 🎜rrreee🎜 比較すると、この 2 つの関係は非常に密接であることがわかります。履歴ライブラリは、履歴オブジェクトよりも強力です。 🎜🎜createHashHistory ソース コード分析🎜🎜 以下では、3 つの履歴タイプの 1 つである hashHistory を例として履歴ソース コードを分析し、その動作を確認します。まず、ハッシュの変更がどのように処理されるかを見てみましょう。 🎜rrreee🎜 上記は、パッシブなハッシュ変更を処理するためのロジックを 1 つの文で要約すると、次のように要約できます: ハッシュ変更イベントをサブスクライブし、変更が本当に必要かどうかを判断し、変更が必要な場合は独自の属性を更新します。変更が必要ない場合は、前の状態に戻ります。 🎜🎜transitionManager の動作を見てみましょう。ユーザー確認ジャンプ関連のコンテンツは無視して、発行/サブスクリプション関連のコンテンツに注目してください。 🎜rrreee🎜 ここのコードは、サブスクライバーのリストを管理し、ハッシュが変更されたときに関連する関数に通知することが一目瞭然です。 🎜🎜上記はハッシュ変更時のパッシブ更新に関連する内容です。push を例として、replace に関連するコードを見てみましょう。似ている。 🎜rrreee🎜ブラウザが前進および後退操作を実行するとき、履歴ライブラリは実際には HTML5 履歴オブジェクトを操作することによって実装されます。 🎜rrreee🎜 window.history.go が呼び出されると、ハッシュが変更され、hashchange イベントがトリガーされ、履歴ライブラリが関連するサブスクライバーに変更を通知します。 🎜🎜概要🎜🎜この記事では、React Router コアが依存する履歴ライブラリについてより詳しく紹介します。 HTML5 の新しい履歴オブジェクトから始めて、その密接な関係と履歴ライブラリを比較し、例として hashHistory を使用して、そのコードの実装詳細を詳細に分析します。 🎜🎜最後に、履歴ライブラリが何をしたかを確認してみましょう: 🎜🎜🎜🎜 HTML5 履歴オブジェクトの概念から学び、それに基づいていくつかの機能を拡張します 🎜🎜🎜🎜 3 種類の履歴を提供します:browserHistory、hashHistory、memoryHistory、統一された API を維持します🎜🎜🎜🎜 パブリッシュ/サブスクライブ機能をサポートし、履歴が変更されると、サブスクリプション機能を自動的にトリガーできます🎜🎜🎜🎜 ジャンプインターセプト、ジャンプ確認、ベース名などの実用的な機能を提供します🎜🎜🎜 🎜履歴ライブラリーですがは React Router の中心的な依存関係であり、React 自体には依存しません。プロジェクトに履歴操作シナリオがある場合は、それをプロジェクトに導入することもできます。 🎜

関連する推奨事項:

h5 を使用して React ドラッグ アンド ドロップの並べ替えコンポーネントを実装する方法 (コード付き)

HTML5 でマージン上部の折りたたみ問題を解決する方法 (コード付き)

タグと共通のものとは何ですかHTML5のルール? HTML5のタグとルールの紹介


以上がReact Router のコア履歴ライブラリの詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
H5:Webコンテンツとデザインの未来H5:Webコンテンツとデザインの未来May 01, 2025 am 12:12 AM

H5(HTML5)は、新しい要素とAPIを介してWebコンテンツと設計を改善します。 1)H5はセマンティックタグ付けとマルチメディアサポートを強化します。 2)キャンバスとSVGを導入し、Webデザインを濃縮します。 3)H5は、新しいタグとAPIを介してHTML機能を拡張することにより機能します。 4)基本的な使用には、それを使用したグラフィックの作成が含まれ、高度な使用法にはwebstorageapiが含まれます。 5)開発者は、ブラウザの互換性とパフォーマンスの最適化に注意を払う必要があります。

H5:Web開発の新機能と機能H5:Web開発の新機能と機能Apr 29, 2025 am 12:07 AM

H5は多くの新しい機能と機能をもたらし、Webページのインタラクティブ性と開発効率を大幅に改善します。 1。SEOの強化などのセマンティックタグ。 2.マルチメディアサポートは、オーディオとビデオの再生とタグを簡素化します。 3. Canvas Drawingは、動的なグラフィックスの描画ツールを提供します。 4.ローカルストレージは、LocalStorageとSessionStorageを介してデータストレージを簡素化します。 5. Geolocation APIは、ロケーションベースのサービスの開発を促進します。

H5:HTML5の重要な改善H5:HTML5の重要な改善Apr 28, 2025 am 12:26 AM

HTML5は5つの重要な改善をもたらします。1。セマンティックタグにより、コードの明確性とSEO効果が向上します。 2.マルチメディアサポートは、ビデオとオーディオの埋め込みを簡素化します。 3。フォームエンハンスメントは、検証を簡素化します。 4.オフラインおよびローカルストレージにより、ユーザーエクスペリエンスが向上します。 5。キャンバスとグラフィック機能は、Webページの視覚化を強化します。

HTML5:標準とWeb開発への影響HTML5:標準とWeb開発への影響Apr 27, 2025 am 12:12 AM

HTML5のコア機能には、セマンティックタグ、マルチメディアサポート、オフラインストレージ、ローカルストレージ、フォームエンハンスメントが含まれます。 1。コードの読みやすさとSEO効果を改善するためのセマンティックタグなど。 2.ラベルでマルチメディアの埋め込みを簡素化します。 3。アプリケーションキャッシュやLocalStorageなどのオフラインストレージとローカルストレージは、ネットワークのない操作とデータストレージをサポートします。 4.フォームエンハンスメントでは、処理と検証を簡素化するための新しい入力タイプと検証プロパティを導入します。

H5コードの例:実用的なアプリケーションとチュートリアルH5コードの例:実用的なアプリケーションとチュートリアルApr 25, 2025 am 12:10 AM

H5は、さまざまな新機能と機能を提供し、フロントエンド開発の機能を大幅に向上させます。 1.マルチメディアサポート:メディアを埋め込んで要素を埋め込み、プラグインは必要ありません。 2。キャンバス:要素を使用して、2Dグラフィックとアニメーションを動的にレンダリングします。 3。ローカルストレージ:ユーザーエクスペリエンスを改善するために、ローカルストレージとセッションストレージを介して永続的なデータストレージを実装します。

H5とHTML5の接続:類似性と相違点H5とHTML5の接続:類似性と相違点Apr 24, 2025 am 12:01 AM

H5とHTML5は異なる概念です。HTML5は、新しい要素とAPIを含むHTMLのバージョンです。 H5は、HTML5に基づくモバイルアプリケーション開発フレームワークです。 HTML5はブラウザを介してコードを解析およびレンダリングしますが、H5アプリケーションはコンテナを実行し、JavaScriptを介してネイティブコードと対話する必要があります。

H5コードの構成要素:キー要素とその目的H5コードの構成要素:キー要素とその目的Apr 23, 2025 am 12:09 AM

HTML5の重要な要素には、最新のWebページの構築に使用される、、,,,,などが含まれます。 1.ヘッドコンテンツを定義します。2。リンクをナビゲートするために使用されます。3。独立した記事のコンテンツを表します。4。ページコンテンツを整理します。5。サイドバーコンテンツを表示します。

HTML5およびH5:一般的な使用法の理解HTML5およびH5:一般的な使用法の理解Apr 22, 2025 am 12:01 AM

HTML5とHTML5の略語であるHTML5とH5の間に違いはありません。 1.HTML5はHTMLの5番目のバージョンであり、Webページのマルチメディア関数とインタラクティブ機能を強化します。 2.H5は、HTML5ベースのモバイルWebページまたはアプリケーションを参照するためによく使用され、さまざまなモバイルデバイスに適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)