Принцип реализации React Router (режим хеширования), который вам нужно знать

React.js
Принцип реализации React Router (режим хеширования), который вам нужно знать

Одностраничные приложения, которые вы должны знать

Что такое одностраничное приложение?

Одностраничное веб-приложение (SPA) — это приложение только с одной веб-страницей. толькоЗагрузите одну HTML-страницу и динамически обновляйте эту страницу по мере того, как пользователь взаимодействует с приложением.веб приложение. а такжеReact,VueЭто основной интерфейсный фреймворк для создания одностраничных приложений.

Сравнение одностраничных приложений и многостраничных приложений

В сравнении одностраничное приложение многостраничное приложение
сочинение Страница оболочки и несколько компонентов страницы (фрагменты) составляют Составление нескольких полных страниц
Ресурсы (css, js) Можно поделиться, нужно только загрузить в оболочку Запрос к серверу при необходимости, независимый от ресурсов
первая загрузка Медленная загрузка на сгиб Существует мало различий между каждой нагрузкой
Пользовательский опыт Пользовательский опыт хороший, изменение контента не требует перезагрузки всей страницы, а последующая нагрузка на сервер невелика. Загрузка страницы медленная, и каждая загрузка требует запроса к серверу
анимация перехода может быть реализован не могу достичь
Поисковая оптимизация (SEO) Эффект плохой, его можно отрендерить через сервер SSR, а стоимость высокая хороший эффект

Принцип одностраничного приложения SPA (роль маршрутизации)

Прислушиваясь к изменениям в маршруте, он сопоставляет компонент, соответствующий маршруту, и сопоставляет компонент с маршрутом. Платформа эффективно обновляет и правильно отображает компоненты при изменении маршрутов.

Процесс внедрения HashRouter, который вам нужно знать

Здесь я представляю принцип реализации и процесс HashRouter.

Три компонента маршрутизации

В React Router есть три типа компонентов:

  1. Маршрутизатор (включая HashRouter и BrowserRouter)

Два режима хэша и истории, соответствующие маршрутизации

  1. компонент сопоставления маршрутов (Route)

Компонент отображения, соответствующий пути управления

  1. компонент навигации (ссылка)

переключение маршрута, прыжок

Ручной процесс внедрения

Возьмите демо в качестве примера

export default class App extends Component {
  render() {
    return (
      <HashRouter>
        <Route path="/home" component={Home}></Route>
        <Route path="/user" component={User}></Route>
      </HashRouter>
    )
  }
}
ReactDOM.render(<App />,
  document.getElementById('root')
);

Здесь компонент Route получает соответствующий путь и компонент для отображения и вкладывается в компонент Router.

Компонент HashRouter

Прежде всего, нам нужно знать некоторые характеристики BOM.

BOMЭто набор API для работы браузера, а окно — это объект верхнего уровня в спецификации, мы можем распечатать некоторую информацию, смонтированную под окном, через this.props, взяв в качестве примера Nuggets.

样例

И реализация HashRouter зависит от этих Api, мы можем передатьwindow.location.hrefПолучите значение URL, где мы находимся.

Конечно, это путь? Подождите, как Route, как вложенный компонент HashRouter, получает путь URL-адреса, соответствующий пути?

Здесь React-Router использует API React.createContext, предложенный React16.3.

Контекст предоставляет способ передачи данных через дерево компонентов.

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

//我们通过一个context.js方法引入这个api
import React from 'react';
let { Provider, Consumer } = React.createContext()
export { Provider, Consumer }

HashRouter действует как производитель черезwindow.addEventListener('hashChange',callback)Прислушивайтесь к изменениям в хеш-значении и передайте его вложенным компонентам.

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

import React, { Component } from 'react';
import { Provider } from './context'
// 该组件下Api提供给子组件使用
class HashRouter extends Component {
  constructor() {
    super()
    this.state = {
      location: {
        pathname: window.location.hash.slice(1) || '/'
      }
    }
  }
  // url路径变化 改变location
  componentDidMount() {
    window.location.hash = window.location.hash || '/'
    window.addEventListener('hashchange', () => {
      this.setState({
        location: {
          ...this.state.location,
          pathname: window.location.hash.slice(1) || '/'
        }
      }, () => console.log(this.state.location))
    })
  }
  render() {
    let value = {
      location: this.state.location
    }
    return (
      <Provider value={value}>
        {
          this.props.children
        }
      </Provider>
    );
  }
}

export default HashRouter;

Компонент маршрута

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

import React, { Component } from 'react';
import { Consumer } from './context'
const { pathToRegexp } = require("path-to-regexp");
class Route extends Component {
  render() {
    return (
      <Consumer>
        {
          state => {
            console.log(state)
            let {path, component: Component} = this.props
            let pathname = state.location.pathname
            let reg = pathToRegexp(path, [], {end: false})
            // 判断当前path是否包含pathname
            if(pathname.match(reg)) {
              return <Component></Component>
            }
            return null
          }
        }
      </Consumer>
    );
  }
}
export default Route;

Поскольку официальная реализация регулярных выражений более сложна, здесь я используюpath-to-regexpЭтот плагин выполняет обычную обработку совпадений.

Осознайте эффект:

Суммировать

В этот раз я просто смоделировал процесс реализации HashRouter, а также имею определенное понимание принципа реализации React-Router. Наконец, процесс обучения сосредоточен на подведении итогов и обмене с удовольствием.Вы можете увидеть мой конкретный код.githubДобро пожаловать, чтобы оставить сообщение и поделиться со мной 😀.