Начиная с принципа маршрутизации, внимательно прочитайте и поймите исходный код react-router 4.0.

внешний интерфейс исходный код браузер React.js

Принцип внешней маршрутизации, такой как   react-router, примерно такой же, который может переключаться и отображать разные страницы без обновления. Суть маршрутизации заключается в том, что при изменении URL-адреса страницы результат отображения страницы может измениться в соответствии с изменением URL-адреса, но страница не будет обновляться. Одностраничные (SPA) приложения могут быть реализованы с помощью внешней маршрутизации.Эта статья начинается с принципа внешней маршрутизации и подробно описывает изменения в принципе внешней маршрутизации. Затем начните с исходного кода react-router4.0 и глубоко поймите, как react-router4.0 реализует интерфейсную маршрутизацию.

  • Внешняя маршрутизация через Hash
  • Внешняя маршрутизация через историю H5
  • Использование React-router4.0
  • Анализ исходного кода React-router4.0

Оригинальный адрес в моем блоге:GitHub.com/fort и все…

Если это поможет, твоя звезда станет для меня лучшей поддержкой~

1. Реализуйте интерфейсную маршрутизацию через Hash

1. Принцип хеша

   Ранняя внешняя маршрутизация была реализована с помощью хеширования:

Изменение хеш-значения URL-адреса не приведет к обновлению страницы.

   Таким образом, интерфейсную маршрутизацию можно реализовать с помощью хеширования, чтобы добиться эффекта отсутствия обновления. Свойство hash находится в объекте location.На текущей странице можно передать:

window.location.hash='edit'

Чтобы изменить хэш-значение текущего URL-адреса. После выполнения вышеуказанного назначения хэша URL-адрес страницы изменяется.

Перед назначением:http://localhost:3000После назначения:http://localhost:3000/#edit

Значений хеша, оканчивающихся на #, в url больше, но до и после присваивания, хотя хэш-значение страницы меняется, меняется полный url страницы, но страница не будет обновляться. Кроме того, существует событие, называемое hashchange, которое может отслеживать изменения хэша.Мы можем отслеживать изменения хэша следующими двумя способами:

window.onhashchange=function(event){
   console.log(event);
}
window.addEventListener('hashchange',function(event){
   console.log(event);
})

Когда значение хеша изменится, выведите HashChangeEvent. Конкретное значение HashChangeEvent:

{isTrusted: true, oldURL: "http://localhost:3000/", newURL:   "http://localhost:3000/#teg", type: "hashchange".....}

   С событием мониторинга и изменением хэш-страницы не обновляется, поэтому мы можем выполнять функцию отображения и скрытия различных дисплеев пользовательского интерфейса в функции обратного вызова события мониторинга, чтобы обеспечить маршрутизацию внешнего интерфейса.

Кроме того, помимо изменения значения хеш-функции текущей страницы через window.location.hash, это также может быть достигнуто через тег a html:

<a href="#edit">edit</a>

2. Недостатки хэша

Хэш имеет хорошую совместимость, поэтому он широко использовался на ранних этапах маршрутизации переднего плана, но использование хэша также имеет много недостатков.

  • Поисковые системы не дружат со страницами с хешами
  • Трудности с отслеживанием поведения пользователей на страницах с хэшем

2. Реализуйте интерфейсную маршрутизацию по истории

В интерфейсе History HTML5 объект History является низкоуровневым интерфейсом и не наследуется ни от какого интерфейса. Интерфейс History позволяет нам манипулировать историей сеансов браузера.

(1) Свойства и методы истории

История предоставляет некоторые свойства и методы.

Свойства истории:

  • History.length: возвращает количество записей в истории сеанса, включая текущую страницу сеанса. Кроме того, если открывается новая вкладка, то значение этой длины равно 1.
  • История.состояние: Сохраняет метод, который вызовет событие popState, и переданный объект атрибута (будет подробно описано в методах pushState и replaceState позже).

Метод истории:

  • History.back(): вернуться на предыдущую страницу в истории сеансов браузера, так же, как кнопка «Назад» в браузере.

  • History.forward(): указывает на следующую страницу в истории сеансов браузера, так же, как кнопка браузера вперед.

  • History.go(): вы можете перейти к указанной странице записи в истории сеансов браузера.

  • History.pushState(): pushState может поместить данные в стек истории сеансов браузера.Этот метод принимает 3 параметра, объект, заголовок и строку URL-адресов. После pushState URL-адрес текущей страницы будет изменен, но не будет обновлен

  • History.replaceState(): replaceState заменяет url страницы текущей сессии на указанные данные, после replaceState url текущей страницы тоже будет изменен, но страница не будет обновляться.

В приведенном выше методе одна и та же точка pushState и ответа:

То есть URL-адрес, отображаемый на текущей странице, будет изменен, но страница не будет обновлена.

разница:

pushState помещается в стек истории сеансов браузера, что увеличивает History.length на 1, а replaceState заменяет текущую историю сеансов, поэтому History.length не будет увеличиваться.

(2) История объекта спецификации

История является важным атрибутом в объектной модели спецификации браузера.История полностью наследует интерфейс истории, поэтому она имеет все атрибуты и методы истории.

Здесь мы в основном рассмотрим свойство history.length и методы history.pushState и history.replaceState.

  • history.pushState(stateObj,title,url) or history.replaceState(stateObj,title,url)

pushState и replaceState принимают 3 параметра, а именно объект состояния, заголовок заголовка и измененный URL-адрес.

window.history.pushState({foo:'bar'}, "page 2", "bar.html");

В этот момент текущий URL становится:

Перед выполнением вышеуказанного метода:http://localhost:3000После выполнения вышеуказанного метода:http://localhost:3000/bar.html

Если мы выведем window.history.state:

console.log(window.history.state); // {foo:'bar'}

window.history.state — это первый объектный параметр нашего pushState.

  • Метод history.replaceState() не изменяет длину хитроя

      console.log(window.history.length);
      window.history.replaceState({foo:'bar'}, "page 2", "bar.html");
      console.log(window.history.length);
    

Длина окна.история.длина двух вышеуказанных выходных данных одинакова.

также.

Каждый раз, когда срабатывает history.back() или кнопка «Назад» браузера, срабатывает событие popstate, которое происходит при переходе назад или вперед:

window.onpopstate=function(event){

}

Уведомление: Методы history.pushState и history.replaceState не запускают события popstate.

Если вы используете историю как основу для маршрутизации, вам нужно использовать history.pushState и history.replaceState, вы можете изменить адрес url без обновления, а если страница откатится назад или вперед, будет запущено событие popstate.

Преимущества маршрутизации на основе истории:

  • Поисковая система
  • Легко подсчитать поведение пользователей

недостаток:

  • Совместимость не так хороша, как хеш
  • Бэкенд должен быть настроен соответствующим образом, иначе при прямом доступе к подстранице возникнет ошибка 404.

3. Использование React-router4.0

Разобравшись с принципом реализации фронтенд-маршрутизации, давайте представим React-router4.0. В кодовую базу React-router 4.0 включены следующие независимые пакеты согласно сценариям использования:

  • react-router : основной код react-router4.0
  • react-router-dom : создавать веб-приложения, основной пакет в сцене объектов DOM.
  • react-router-native : подходит для создания реагирующих приложений.
  • react-router-config : настроить статические маршруты
  • react-router-redux : Настройте маршрутизацию в сочетании с избыточностью.Это устарело и устарело.

В react-router4.0 следуйте концепции дизайна Just Component:

Все предоставляемые API представлены в виде компонентов.

Например, такие API, как BrowserRouter, Router, Link и Switch, используются в виде компонентов.

1. API общих компонентов React-router-dom

Давайте возьмем пакет React-router-dom в React-router 4.0, чтобы представить часто используемые BrowserRouter, HashRouter, Link и Router.

(1) <BrowserRouter>

После обертывания всей системы приложений компонентом интерфейсная маршрутизация без обновления реализуется через историю html5.

Компонент имеет следующие свойства:

  • basename: string Этот атрибут представляет собой подкаталог, который добавляет значение с именем basename к текущему URL-адресу.

      <BrowserRouter basename="test"/>
    

Если установлено свойство basename, то в это время:

http://localhost:3000а такжеhttp://localhost:3000/testУказывает тот же адрес и отображает тот же контент.

  • getUserConfirmation: func Это свойство используется для подтверждения функции навигации. Использовать window.confirm по умолчанию

  • forceRefresh: bool Значение по умолчанию — false, что означает, что страница не будет обновляться при смене маршрута.Если текущий браузер не поддерживает историю, то при установленном для forceRefresh значении true каждый раз при смене URL-адреса вся страница будет обновлен.

  • keyLength: число указывает длину ключевого атрибута местоположения. В react-router есть местоположение, соответствующее каждому URL-адресу, и значение ключа местоположения каждого URL-адреса отличается. Этот атрибут обычно использует значение по умолчанию. маленькое значение.

  • Children: node Свойство Children должно быть узлом ReactNode, представляющим единственный элемент, который нужно отобразить.

соответствует , использует атрибут хеша в URL-адресе, чтобы гарантировать, что страница отображается одновременно без повторного обновления.

(2) <Route>

Компонент очень важен, он сопоставляет адрес в соответствующем месте и отображает соответствующий компонент после успешного сопоставления. Давайте посмотрим на атрибуты в .

Давайте сначала посмотрим, как выполнить сопоставление и определить атрибуты сопоставления адреса :

  • путь: когда URL-адрес в местоположении изменяется, он будет соответствовать атрибуту пути в маршруте.Путь определяет эффект рендеринга, связанный с маршрутом или URL-адресом.

  • точно: Если точно, только URL-адрес точно совпадает с путем, он будет совпадать. Если нет точного атрибута, адреса URL-адресов не совсем совпадают и также будут совпадать.

Например, когда точное не установлено:

<Route  path='/home' component={Home}/> 
<Route  path='/home/first' component={First}/> 

На данный момент URL-адрес:http://localhost:3000/home/first, он будет соответствовать не только компоненту First, если path='/home/first', но и маршрутизатору, если path='home'.

Если установлено точное:

 <Route  path='/home' component={Home}/> 

Только http://localhost:3000/home/first не будет соответствовать компоненту Home, только URL-адрес точно совпадает с путем, и только http://localhost:3000/home может успешно соответствовать компоненту Home.

  • strict: В отличие от точного, строгий атрибут является только дополнением к точному атрибуту.После того, как строгий атрибут установлен, он строго ограничен, но косая черта "/".

Например, если параметр strict не установлен:

 <Route  path='/home/' component={Home}/> 

На данный момент http://localhost:3000/home иhttp://localhost:3000/home/может соответствовать компоненту Home. Сопоставление более слабое для косой черты "/". Если установлен строгий атрибут:

<Route  path='/home/' component={Home}/> 

Затем, существует ли косая черта строгого соответствия в это время,http://localhost:3000/homeне будет соответствовать компоненту Home.

Когда компонент маршрута успешно соответствует URL-адресу, он продолжит рендеринг. Итак, какой атрибут определяет, какой компонент или стиль отображать, а компонент, визуализация и дочерние элементы Route определяют отображаемое содержимое.

  • компонент: это свойство принимает компонент React, и когда URL-адрес успешно совпадает, компонент будет отображаться
  • render: func Это свойство принимает функцию, которая возвращает элемент React. Когда URL-адрес успешно совпадает, возвращенный элемент визуализируется.
  • дочерние элементы: аналогично рендерингу, принимает функцию, которая возвращает элемент React, но разница в том, что содержимое дочерних элементов всегда будет отображаться независимо от того, соответствует ли URL-адрес пути текущего маршрута или нет.

И методы или компоненты, принимаемые этими тремя свойствами, будут иметь три параметра местоположения, совпадения и истории. Если это компонент, местоположение, совпадение и история будут переданы по ссылке в свойствах компонента.

(3) <Link>

определяет правила сопоставления и правила рендеринга, а определяет, как изменить URL-адрес на странице, чтобы он соответствовал соответствующему . аналогичен тегу a в html. Кроме того, когда изменяет URL-адрес, некоторые атрибуты могут быть переданы успешно сопоставленному маршруту для использования при отображении соответствующего компонента.

  • нанизывать Значение атрибута to может быть строкой, которая совпадает с href тега a в html.Даже если значение атрибута to является строкой, щелкнув тег Link, чтобы перейти к маршруту соответствующего путь также изменит историю, местоположение, совпадение. Эти три объекта передаются в реквизиты компонента, соответствующего маршруту.

Например:

<Link to='/home'>Home</Link>

Как показано выше, когда to принимает строку, он переходит к маршруту, чей URL-адрес «/home», и отображает связанный с ним компонент, чтобы принять 3 объекта: историю, местоположение и совпадение. Эти три объекта будут подробно описаны в следующем подразделе.

  • для объекта Значением атрибута to также может быть объект, который может содержать следующие атрибуты: pathname, searchh, hash и state.Первые три параметра относятся к тому, как изменить URL-адрес, а последний параметр состояния — к изменению URL-адреса. соответственно Передайте параметр объекта.

Например:

 <Link to={{pathname:'/home',search:'?sort=name',hash:'#edit',state:{a:1}}}>Home</Link>

В предыдущем примере to — это объект. После нажатия тега Link для перехода измененный URL-адрес: '/home?sort=name#edit'. Но при сопоставлении с соответствующим маршрутом он соответствует только компонентам, путь которых «/home», «/home?sort=name#edit». Параметры после '/home' не используются в качестве критериев соответствия, а передаются только в качестве параметров совпавшему компоненту. Кроме того, state={a:1} также передается в качестве параметра вновь визуализируемому компоненту.

(4) Объект истории передается реквизитам компонента в React-router.

После введения , и можно создать простое приложение React-маршрутизатора, используя эти 3 API компонента. Здесь мы говорили ранее, что всякий раз, когда вы нажимаете на метку Link для перехода или используете метод React-router для перехода в js, из текущего отображаемого компонента, введите новый компонент. Когда новый компонент визуализируется, он примет параметр, переданный от старого компонента.

Как мы упоминали ранее, если маршрут соответствует соответствующему измененному URL-адресу, будет отображаться новый компонент. Реквизиты в новом компоненте включают три атрибута объекта: историю, местоположение и совпадение. Среди них наиболее важным является атрибут объекта истории. .

Также возьмите следующий пример для иллюстрации:

<Link to={{pathname:'/home',search:'?sort=name',hash:'#edit',state:{a:1}}}>Home</Link>

<Route exact path='/home' component={Home}/>

Мы использовали , который использует объект window.history. При нажатии тега Link для перехода будет отображаться новый компонент Home. Мы можем вывести историю в реквизитах в компоненте Home:

// props中的history
action: "PUSH"
block: ƒ block()
createHref: ƒ createHref(location)
go: ƒ go(n)
goBack: ƒ goBack()
goForward: ƒ goForward()
length: 12
listen: ƒ listen(listener)
location: {pathname: "/home", search: "?sort=name", hash: "#edit", state: {…}, key: "uxs9r5"}
push: ƒ push(path, state)
replace: ƒ replace(path, state)

Из приведенной выше разбивки собственности:

  • push:f Этот метод используется для изменения URL-адреса в js. Ранее URL-адрес можно было изменить в виде HTML-тегов в компоненте Link. Метод push сопоставляется с методом pushState в window.history.

  • replace: f Этот метод также используется для изменения URL-адреса в js, а метод замены сопоставляется с методом replaceState в window.history.

  • block: f Этот метод также очень полезен, например, когда пользователь покидает текущую страницу, пользователю дается текстовое приглашение, а также приглашение вида history.block("Вы уверены, что хотите покинуть текущую страницу? ") может быть использован.

  • go / goBack / goForward

Методы истории go, goBack и goForward в реквизитах компонента соответствуют window.history.go, window.history.back и window.history.forward соответственно.

  • действие: "НАЖАТЬ" || "ПОЛНЯТЬ" Атрибут действия очень большой, если текущий url изменить через тег Link или метод this.props.push в js, то действие в новом компоненте будет "PUSH", иначе - "POP".

Атрибут действия очень полезен. Например, когда мы делаем анимацию перелистывания страниц, анимация вперед — это SlideIn, а анимация назад — SlideOut. Мы можем судить, какую анимацию использовать, в соответствии с действием в компоненте:

function newComponent (props)=>{
   return (
     <ReactCSSTransitionGroup
          transitionAppear={true}
          transitionAppearTimeout={600}
          transitionEnterTimeout={600}
          transitionLeaveTimeout={200}
          transitionName={props.history.action==='PUSH'?'SlideIn':'SlideOut'}
         >
           <Component {...props}/>
    </ReactCSSTransitionGroup>
   )
}
  • местоположение: объект В атрибуте местоположения нового компонента записываются параметры, переданные от предыдущего компонента.Из приведенного выше примера мы видим, что значение местоположения в это время равно:

      hash: "#edit"
      key: "uxs9r5"
      pathname: "/home"
      search: "?sort=name"
      state: {a:1}
    

За исключением ключа, который используется как единственное представление, другие атрибуты — это параметры, которые мы передали из предыдущего тега Link.

Четыре, анализ исходного кода React-router4.0

В третьем разделе мы представили общее использование React-router и прочитали исходный код React-router 4.0.

Здесь мы в основном анализируем, как React-router 4.0 реализует интерфейсную маршрутизацию на основе window.history, поэтому спроектированными компонентами являются BrowserRouter, Router, Route и Link.

1. История в React-маршрутизаторе

Из введения в предыдущем разделе мы знаем, что в пропсах есть объект истории, который передается вновь отображаемому компоненту, щелкнув тег Link.Этот объект имеет богатый контент, такой как: действие, возврат, переход, местоположение, нажатие, и заменить методы.

React-router создает класс History для создания экземпляров с более богатыми свойствами на основе window.history. После создания экземпляра класса History у него есть такие методы, как action, goBack, location и так далее.

React-router разделяет метод построения этого нового класса History на пакет узлов с именем history.

npm install history -s 

Его можно ввести с помощью вышеуказанного метода, давайте посмотрим на реализацию этого класса History.

const createBrowserHistory = (props = {}) => {
    const globalHistory = window.history;
    ......
    //默认props中属性的值
    const {
      forceRefresh = false,
      getUserConfirmation = getConfirmation,
      keyLength = 6,
      basename = '',
    } = props;
    const history = {
        length: globalHistory.length,
        action: "POP",
        location: initialLocation,
        createHref,
        push,
        replace,
        go,
        goBack,
        goForward,
        block,
        listen
    };                                         ---- (1)
    const basename = props.basename;   
    const canUseHistory = supportsHistory();   ----(2)
            
    const createKey = () =>Math.random().toString(36).substr(2, keyLength);    ----(3)
    
    const transitionManager = createTransitionManager();  ----(4)
    const setState = nextState => {
        Object.assign(history, nextState);
    
        history.length = globalHistory.length;
    
        transitionManager.notifyListeners(history.location, history.action);
    };                                      ----(5)
    
    const handlePopState = event => {
        handlePop(getDOMLocation(event.state));
    };
    const handlePop = location => {
    if (forceNextPop) {
      forceNextPop = false;
      setState();
    } else {
      const action = "POP";
      
      transitionManager.confirmTransitionTo(
            location,
            action,
            getUserConfirmation,
            ok => {
              if (ok) {
                setState({ action, location });
              } else {
                revertPop(location);
              }
            }
          );
        }
    };                                    ------(6)
    const initialLocation = getDOMLocation(getHistoryState());
    let allKeys = [initialLocation.key]; ------(7)
    
  
    // 与pop相对应,类似的push和replace方法
    const push ... replace ...            ------(8)
    
    return history                        ------ (9)
    
}
  • (1) В объекте истории указывается, что новый метод построения История вернула как атрибут.

  • (2) Метод определения SupportHistory текущего браузера window.history для совместимости следующим образом:

     export const supportsHistory = () => {
       const ua = window.navigator.userAgent;
     
       if (
         (ua.indexOf("Android 2.") !== -1 || ua.indexOf("Android 4.0") !== -1) &&
         ua.indexOf("Mobile Safari") !== -1 &&
         ua.indexOf("Chrome") === -1 &&
         ua.indexOf("Windows Phone") === -1
       )
         return false;
     
       return window.history && "pushState" in window.history;
     };
    

Из приведенного выше дискриминанта видно, что window.history абсолютно поддерживается в chrome, mobile safari и windows phone, но не поддерживает Android 2.x и Android 4.0.

  • (3) используется для создания уникального идентификационного ключа с указанным количеством цифр, связанных с каждой записью URL-адреса в истории, а длина ключа по умолчанию составляет 6 цифр.

  • (4) Метод createTransitionManager в (4) возвращает интегрированный объект, который содержит исторический адрес или функцию слушателя при изменении объекта Конкретный код выглядит следующим образом:

       const createTransitionManager = () => {
           const setPrompt = nextPrompt => {
             
           };
     
           const confirmTransitionTo = (
             location,
             action,
             getUserConfirmation,
             callback
           ) => {
              if (typeof getUserConfirmation === "function") {
                   getUserConfirmation(result, callback);
                 } else {
                   callback(true);
                 }
               } 
           };
           
           
           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));
           };
         
           return {
             setPrompt,
             confirmTransitionTo,
             appendListener,
             notifyListeners
           };
    

};

Функция setPrompt используется для установки текстовой подсказки, которая появляется при переходе по URL-адресу.Функция confirmTransaction будет генерировать местоположение, действие, обратный вызов и другие параметры нового объекта истории.Входящие объекты местоположения и действия.

Затем мы видим, что существует массив слушателей, в котором хранится серия массивов событий прослушивания, связанных с URL-адресами. С помощью следующего метода appendListener события могут быть добавлены в этот массив, а с помощью метода notifyListeners все события в массиве слушателей могут пройти и выполнить.

  • (5) Метод setState, который возникает, когда URL-адрес истории или действие истории изменяется, этот метод обновит атрибуты в объекте истории и вызовет метод notifyListeners, передав текущую историю. .действие. Пройдите и выполните все прослушиватели событий, которые прослушивают изменения URL-адреса.

  • (6) Этот метод getDOMLocation предназначен для создания объекта атрибута местоположения новой истории на основе текущего значения в window.state.AllKeys — это ключ, связанный с историческим URL-адресом, который всегда поддерживается при изменении URL-адреса и хранится глобально, и allKeys выполняется.При создании "POP" или "PUSH", "Repalce" и других методов, которые изменяют URL-адрес, он будет поддерживать обновление в реальном времени.

  • (7) Метод handlePop используется для обработки события "POP". Мы знаем, что щелчок назад в window.history вызовет событие "POP". То же самое и здесь. Действие выполнения - "POP", которое будет срабатывает при бэк.функции.

  • (8) содержит методы push и replace, аналогичные методу pop. То же самое, что делает метод push, заключается в выполнении действия как «PUSH» («REPLACE»), которое изменяет значение в массиве allKeys. Единственное отличие состоит в том, что действие заключается в том, что метод «PUSH» нажимает на добавление в массив allKeys, а метод «REPLACE» для замены действия — на замену текущего элемента.

  • (9) Верните вновь сгенерированный объект истории.

2. Компонент Link в React-маршрутизаторе

На самом деле, самое сложное для понимания — это как пересобрать функцию фабрики истории в React-router.В первом разделе мы подробно представили исходный код функции генерации истории createBrowserHistory, а дальше легко посмотреть компонент «Ссылка».

Во-первых, компонент Link похож на тег a в HTML, и его назначение очень простое: активировать метод изменения URL-адреса и метод активного изменения URL-адреса.Из приведенного выше введения в историю, известно, что используются методы push и replace, поэтому исходный код компонента Link для:

class Link extends React.Component {

    
   handleClick = event => {
   ...

     const { history } = this.context.router;
     const { replace, to } = this.props;
     if (replace) {
       history.replace(replace);
     } else {
      history.push(to);
     }
   }
  };
  render(){
    const { replace, to, innerRef, ...props } = this.props;
     <a {...props} onClick={this.handleClick}/>
  }
}

Приведенный выше код очень прост: получите историю из глобального объекта контекстного API React, а затем выполните history.replace(to), если replace имеет значение true в свойствах, переданных компоненту Link, to является объектом, содержащим путь, если он передан. свойство компонента Link имеет значение false, выполняется метод history.push(to).

3. Компонент роута в React-router

Компонент Route тоже очень простой, он принимает один из самых важных атрибутов path в своих реквизитах, Route делает только одно:

Когда URL-адрес изменяется, атрибут пути сравнивается с измененным URL-адресом, и, если совпадение успешно, отображается компонент, назначенный компонентом или дочерним атрибутом компонента.

Конкретный исходный код выглядит следующим образом:

class Route extends React.Component {


  ....
  constructor(){
  
  
  }
  render() {
    const { match } = this.state;
    const { children, component, render } = this.props;
    const { history, route, staticContext } = this.context.router;
    const location = this.props.location || route.location;
    const props = { match, location, history, staticContext };

    if (component) return match ? React.createElement(component, props) : null;

    if (render) return match ? render(props) : null;

    if (typeof children === "function") return children(props);

    if (children && !isEmptyChildren(children))
      return React.Children.only(children);

    return null;
  }

}

Совпадение в состоянии является меткой того, соответствует ли оно.Если оно соответствует пути текущего маршрута, то компонент React, на который он указывает, отображается в соответствии с атрибутом компонента порядка приоритета, атрибутом рендеринга и атрибутом потомков.

4. Компонент Router в React-router

В компоненте Router это базовый компонент BrowserRouter, HashRouter и других компонентов. В этом компоненте определена функция сопоставления, содержащая правило сопоставления, а метод прослушивателя в новой истории используется для отслеживания изменения URL-адреса, так что при изменении URL-адреса результаты isMatch различных компонентов пути в маршрутизаторе измененный.

class Router extends React.Component {
    componentWillMount() {
        const { children, history } = this.props
        
        //调用history.listen监听方法,该方法的返回函数是一个移除监听的函数
        
        this.unlisten = history.listen(() => {
          this.setState({
            match: this.computeMatch(history.location.pathname)
          });
        });
    }
    componentWillUnmount() {
      this.unlisten();
    }
    render() {
    
    }
}

Вышеупомянутый сначала вызывает метод мониторинга прослушивателя, прежде чем компонент будет создан для отслеживания изменения URL-адреса и обновления результата isMatch в режиме реального времени.

5. Резюме

Начиная с принципа внешней маршрутизации, в этой статье представлены два часто используемых метода внешней маршрутизации, затем представлен API базового компонента и использование React-router, подробно представлен недавно созданный объект истории в компонентах React-router, и, наконец, объединяет React.-Router API Прочтите исходный код React-router.