Как да изградите свой собствен React-Router с нов React Context Api

Снимка на Крис Барбалис на Unsplash

React Context не е нещо ново за разработчиците на react.js, но това е нещо, което винаги се е използвало от най-смелите (React-Redux, React-Router, ...), дори в самата документация е била отхвърлена. Това обаче се промени с пускането на новата версия на React 16.3, която се появи с официална версия на нов API за работа с контекста.

Първо искам да се извиня за тази непретенциозна статия, тя беше написана въз основа на последните ми експерименти върху новата версия на React и кодът, който намерихте тук, беше извлечен от нея. React-Router е много повече от това, което представям, но този пример ще ви обясни как можете да развиете нещо подобно, като използвате новия контекст api.

Контекстът

Контекстите са начин за преминаване на състояние отгоре надолу (родител към внуци), без да се налага разпространението на това състояние към междинни компоненти (деца).

Нов API на React Context

Новият API на React Context има три основни части:

От dailyjs:

  • „React.createContext, който е предаван първоначалната стойност (и по избор фантазирана функция за отказ, която използва битмаска). Това връща обект с доставчик и потребител “
  • „Компонентът на доставчика се използва по-високо в дървото и приема стойност на опора, наречена стойност (която може да бъде всичко).“
  • „Потребителският компонент се използва навсякъде под доставчика в дървото и приема опора, наречена„ деца “, която трябва да бъде функция, която приема стойността и трябва да върне реагиращ елемент (JSX).“

Изграждане на собствен React-Router

Кодът от този пример има малко повече от 40 реда.

Какво искаме?

Ще искаме нашето приложение да показва компоненти, когато даден маршрут съвпада с URL адреса.

Нещо като това:

  
  
  

И, разбира се, искаме да можем да преминем към определен URL адрес:

 Потребители 

Зависимостите

Няма да изобретявам колелото, ще използваме повечето същите зависимости като самия React-Router.

За да се справим с pushstate, ще използваме историята на браузъра вместо историята.

прежда добавете история на браузъра

За адресиране на маршрутите ще използваме pathToRegexp

прежда добавете път към регекс

Създайте контейнер за контекст на рутер

На първо място ще трябва да създадем файл Context Container, където ще управляваме състоянието на рутера и ще създадем действията за навигация между URL адреси.

Във файл Router.js ще добавим следното:

import React, {createContext} от 'react';
история на импортиране от „история на браузъра“;
const началоState = {
    url: window.location.pathname
};
const Context = createContext ()
const {Доставчик, Потребител} = Контекст;

Първите 9 реда импортират необходимите libs, инициализират състояние, създават контекстен обект и извличат Доставчик и Потребител от контекст.

Ще използваме Доставчика, за да запазим контекста и да експортираме Потребителя, който да бъде използван от Приложението, за да имаме достъп до състоянието и действията.

клас маршрутизатор разширява React.Component {
    състояние = първоначално състояние;
    действие = {
        go: (url) => this.setState (
                състояние => ({... състояние, URL}),
                () => история (URL)
            )
    };
    компонентDidMount () {
        история ((e, url) => this.setState (state => ({... state, url})));
    }
    render () {
        връщане <Стойност на доставчика = {{state: this.state, action: this.action}}> {this.props.children} ;
    }
}
износ {Рутер по подразбиране, Потребител,};

Използване на Router Context Provider

В приложението си може да имате нещо подобно и да използвате рутера така:

импортиране на рутер от „./Router“;
// ... реагирайте на импортиране, вие с лентата с инструменти и вашия компонент със съдържание
клас приложение разширява React.Component {
  render () {
    връщане (
      
        
        <Съдържание />
      
    );
  }
}
приложение за експортиране по подразбиране;
Сега можете да използвате компоненти на Route и Link, но първо първо използвайте тези два.

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

Създайте файл Route.js и го добавете.

import React от 'реагира';
импортиране на pathToRegexp от 'path-to-regexp';
import {Consumer} от './Router';
експортиране по подразбиране функция Route (реквизит) {
    връщане (<Потребител>
        {({state}) => {
            const re = pathToRegexp (props.path);
            ако (re.test (state.url)) върне props.children;
        }}
    );
}

Използване на вашия маршрут компонент

Например във вашия компонент за съдържание можете да имате този код:

// ...
import {Consumer} от './Router';
импортиране на маршрут от './Route';
експорт по подразбиране функция Съдържание (подпори) {
    връщане 
        <Потребителите>
            {({състояние, действие}) => {
                връщане 
                     
main
                                                          
            }}              ; }

Както виждате в реализацията на компонента на маршрута, „пътят“ ще бъде тестван, за да се види дали съответства на текущото състояние на доставчика на контекст на рутера.

Компонент за връзка

За да се придвижвате между URL адреси, можете директно да използвате изложените действия от Потребителя на маршрутизатора:

import {Consumer} от './Router';
// ...
<Потребителите>
    {({action}) => 
        
        <Бутон color = "наследяване" onClick = {() => action.go ('/ products')}> Продукти 
    }

Или можете да реализирате своя собствен компонент за връзка така:

import React от 'реагира';
import {Consumer} от './Router';
експортиране по подразбиране функция Връзка ({път, ... подпори}) {
    връщане (<Потребител>
        {({action}) =>  action.go (path)} />}
    );
}

Този вид реализации, използващи контекст, не са нещо ново, те съществуват в много известни libs, въпреки това се надявам да ви помогнат да разберете малко как можете да използвате API на New React Context и колко лесно е да го използвате в свой собствен проекти.

Можете да намерите кода на GitHub:

Благодаря на Joaquim Ley (Joaquim Ley) за вашия преглед и отделеното време.