Рубрики
Без рубрики

Завоевать навигационное состояние с реагированным маршрутизатором и redux

Фундаментальный компонент традиционных приложений и приложений для одиночных страниц – NaviCatio … Помечено в React, FrontendDev, WebDev, JavaScript.

Фундаментальный компонент традиционных приложений и приложений для одиночных страниц – это навигация – возможность перемещаться с одной страницы в другую.

Хорошо, и так что?

Подожди!

В этой статье я не только покажу вам нюансы навигации в рамках приложений React/Redux, я покажу вам, как это сделать декларативно! Вы также узнаете, как поддерживать состояние навигационные коммутаторы вашего приложения.

Готовый?

👉 NB: В этой статье я предполагаю, что у вас приличное понимание того, как Redux работает. Если нет, вы можете проверить мою статью о Понимание Redux. 📕.

Приложение мы будем работать с

В заявке, чтобы сделать это как можно более прагматично, я настроил простое приложение для этой цели.

Следующий GIF является то, что Эмохиленнд.

Здравствуйте, эмозиланнд!

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

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

В реальном мире это поддельные действия могут быть сетевой просьбой получить некоторые ресурсы или любые другие асинхронизированные действия.

Просто так мы на одной странице, позвольте мне немного поделиться на том, как Эмодзиландь Приложение построено.

Быстрый обзор того, как emojiland построен

Работать вместе, возьмите заявку Repo из Github Отказ Если вы чувствуете себя ленивым, не стесняйтесь пропустить.

Клонировать репо: Гит клон https://github.com/ohansemmanuel/nav-state-react-router.git

Перейдите в каталог: CD Nav-State-React - маршрутизатор

Установите зависимости: Пряжа устанавливает или NPM установить

Затем запустите приложение: Пряжа начать или NPM Начало

Сделал это?

Приложение является основным реагированием с настройкой Redux. Очень минимальное настроение с реагированным маршрутизатором также включено.

В Контейнеры/app.js. Вы найдете 6 маршрутов, содержащихся в этом приложении.

Ниже приведено полное представление кода:

const App = () => (
  
    
      
      
      
      
      
      
    
  
);

Каждый маршрут приводит к компоненту Emoji. /тихий оказывает Боевик компонент.

И вот что Боевик Компонент выглядит как:

import React from "react";
import EmojiLand from "../components/EmojiLand";
import keepQuietImg from "../Images/keepquiet.png";
import emojiLand from "./emojiLand";
const KeepQuiet = ({ appState, handleEmojiAction }) => (
    
  );
export default emojiLand(KeepQuiet);

Это простой функциональный компонент, который отображает компонент эмозиланда. Конструкция компонента эмозиланда в Компоненты/emojiland.js Отказ

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

Что важно, так это то, что он принимает в некоторых реквизитах, таких как градиент фона, изображение и текст кнопки.

Чем более деликатный – это экспортированный компонент.

Пожалуйста, посмотрите на последнюю строку блока кода выше.

export default emojiLand(KeepQuiet);

Emojiland прямо есть компонент более высокого порядка. Все это делает, это убедиться, что при нажатии кнопки в любой из компонентов Emoji Это имитает поддельные действия около 1000 мс. Помните, что на практике это может быть сетевой запрос.

Компонент Emojiland более высокого порядка делает это, передавая appstate реквизиты в компоненты Emoji. В этом примере, Соблюдайте тишину

Когда любой из компонентов Emoji впервые отображается, AppState является пустой строкой, "" Отказ После примерно 1000 мс, appstate изменяется на Do_something_over Отказ

Где Do_something_over представлен как постоянный, как показано ниже:

В константах/типах действий:

export const DO_SOMETHING_OVER = "DO_SOMETHING_OVER";

Теперь, вот как работает каждый компонент Emoji в этом приложении!

Также помните, что на каждом маршруте оказываются отдельный компонент эмозиланда.

Angrydude, beexcicted & bequiet

SmileLady, ThinkHard, Thumbsup

Перенаправляясь как чемпион

По завершении поддельного процесса, давайте предположим, что вы хотите перенаправить/перейти на другой маршрут в пределах Эмодзиландь заявление.

Как ты делаешь это?

Во-первых, помните, что при попадании на домашний маршрут, что оказывается компонентом TheAngryDude.

Компонент Angrydude.

Чем более декларативный подход для обработки перенаправления состоит в том, чтобы использовать компонент Redirect от React-Router.

Позвольте мне показать вам, как.

Поскольку мы хотим перенаправить из компонента AngryDude, сначала вы импортируете компонент Redirect в контейнерах/AngryDude.js, как это:

import { Redirect } from "react-router-dom";

Для перенаправления на работу он должен быть оказан как обычный компонент. В нашем конкретном примере мы будем перенаправлять, когда appstate удерживает значение, Do_something_over. I.e поддельные действия были завершены.

Теперь вот код для этого:

const AngryDude = ({ appState, handleEmojiAction }) => {
    return appState === DO_SOMETHING_OVER ? (

    ) : (
      

Теперь, если appstate равно Do_something_over. , компонент Redirect оказывается.


Обратите внимание, что требуется для опоры добавляется в компонент Redirect. Этот опоры обязан знать Где перенаправить на.

С этим на месте вот что в действии:

Перенаправление от «злого» до «пальцы вверх»

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

Вот что в действии:

Перенаправляя через все маршруты!

Это было легко, верно?

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

Избегать перенаправления от замены текущего маршрута в истории

Я открою новый браузер и щелкнул по приложению, но в какой-то момент я попытаюсь вернуться I.e, используя кнопку Back Browser.

Посмотрите ниже:

Попытка «вернуться» возвращает меня в домашнюю страницу браузера:(

Обратите внимание, что когда я нажимаю кнопку «Назад», она не вернется к предыдущему маршруту, но возвращает меня к домашней странице моего браузера.

Почему?

Это связано с тем, что по умолчанию с использованием компонента Redirect заменит текущее местоположение в стеке истории браузера.

Итак, даже если мы зацикливаем несколько маршрутов, маршруты заменили друг друга в «записи браузера».

В браузере мы посетили только один маршрут. Таким образом, нажатие на заднюю кнопку отвезла меня к домашней странице.

Это как наличие массива – но вместо того, чтобы нажать на массив, вы заменяете текущее значение в массиве.

Хотя есть исправление.

Компонент Redirect может принять прижимной опоры, который деактивирует этому поведению. С помощью Push Prup каждый маршрут нажата на стек истории браузера и не заменена.

Вот как это выглядит в коде:

return appState === DO_SOMETHING_OVER ? (
    
  ) : (
    
  );

И вот результат этого.

Теперь нажав на заднюю кнопку работает так, как ожидается:)

Обратите внимание, как мы можем теперь перейти к ранее посещенным маршрутам!

Поддержание состояния навигации

При перемещении от одного пути к другому переменные на предыдущем маршруте не переносятся на следующий маршрут. Они ушли!

Да прошло, за исключением того, что вы работаете на вашем конце.

Что интересно, так это то, что компонент Redirect делает это довольно легко.

В отличие от передачи строки для опоры на перенаправить, вы также можете пройти в объекте.

Вы также можете пройти в объекте к компоненту Redirect

Что интересно, в том, что с представлением объекта вы также можете пройти в государственном объекте.

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

Добавление объекта состояния в пределах «до».

Давайте посмотрим пример в коде.

При перенаправлении от компонента AngryDude в Thumbsup давайте передам некоторые значения в поле государства.

Вот что у нас было раньше:


Это следует изменить на это:


Теперь я прошел в 3 разных парах ключевых ценностей! Юманнип, возраст и секс.

Но при перенаправлении на маршрут/Thumbs, как я могу получить эти ценности?

Для компонентов маршрута реагирующий маршрутизатор предоставляет определенное расположение. В пределах этого опоры расположения вы можете получить доступ к объекту состояния, как это, location.state или this.props.location.State.

NB: Компоненты маршрута являются компонентами, отображаемыми компонентами реагирования. Они обычно в подписи,

Вот пример меня введя государственный объект, полученный в новом маршруте,/Thumbs Внутри недавно оказанных больших пальцев.

const ThumbsUp = ({ appState, handleEmojiAction, location }) => {
console.log(location.state);
  return appState === DO_SOMETHING_OVER ? (
    
  ) : (
    
  );
};

Обратите внимание, как определение опора расположения деконструируется, а затем есть Console.log (location.state).

После перенаправленного, и консоль DEV проверен, государственный объект действительно прямо там!

Государственный объект получен и зарегистрирован в новом /Thumbs. маршрут!

Вы можете даже пойти немного дальше и на самом деле представьте какой-то компонент пользовательского интерфейса на основе прошлого государства.

Вот что я сделал:

Посмотрите на текст ниже кнопки. Значения были схвачены из объекта состояния местоположения!

Прихватив государство, переданное в Thumbsup, я сопоставил его и отобразил значения ниже кнопки. Если вы заботитесь о том, как я это сделал, посмотрите на исходный код в Компоненты/emojiland.js.

Теперь мы сделали достойный прогресс!

Любая реальная мировая ценность?

Возможно, вы задумались все время, – Да, это круто, но где я использую его в реальном мире? »

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

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

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

Но есть еще одно решение!

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

Предположим, что мы хотели быть перенаправлены на маршрут из/больших пальцев на тихий маршрут после выполнения некоторых действий. В этом случае мы хотим сделать это без используя компонент Redirect.

Как бы вы пойдете об этом?

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

История. ПУШ ("/тихо) или this.props.history.push ("/тихий")

Хорошо, но откуда этот объект истории?

Также как расположение в предыдущем примере, React-маршрутизатор также передает историю опоры на компоненты маршрута.

Вот что у нас было в контейнерах/Thumbs.js:

const ThumbsUp = ({ appState, handleEmojiAction, location }) => {
  return appState === DO_SOMETHING_OVER ? (
    
  ) : (
    
  );
};

Теперь мы можем использовать объект истории, как это:

const ThumbsUp = ({ appState, handleEmojiAction, location, history }) => {
  if (appState === DO_SOMETHING_OVER) {
history.push("/quiet");
  }
  return (
    
  );
};

И теперь результаты так же одинаковы:

Использование опоры истории работает так же хорошо!

Как и ожидалось, мы все еще имели возможность перенаправления!

Важно отметить, что вы также можете пройти в некоторые значения состояний, как это:

history.push("/quiet", {
 hello: "state value"
})

Просто пропустите второй параметр объекта в историю.

У нас все это из коробки

Вы понимаете, что нам не пришлось делать какие-либо «дополнительные» работы на стороне redux?

Все, что нам нужно было сделать, это изучить API-маршрутизатор API-маршрутизатора. Это хорошо, и это объясняет тот факт, что React-Router и Redux работают просто из коробки.

Это приложение использует Redux, но это не проблема.

Понял?

Что-то (или, возможно, может быть) неправильно с нашим подходом

На самом деле, ничего не так с подходами, которые мы обсуждали до сих пор. Они работают просто хорошо!

Тем не менее, есть несколько предостережений, и в зависимости от того, как вы любите работать, или проект, над которым вы работаете, вы не можете найти их непосредственно.

Уменьшите вам, я работал с предыдущими шаблонами в крупномасштабном проекте, и они работают просто хорошо.

Тем не менее, много redux Пуристы предпочел бы иметь возможность перемещаться по маршрутам путем диспетчеризации действий. Поскольку это основной способ провоцирования государственного изменения.

Кроме того, многие также предпочитают синхронизировать данные маршрутизации с помощью магазина Redux I.E, чтобы данные маршрута, сохраненные в магазине Redux.

Наконец, они также жаждут возможности наслаждаться поддержкой для отладки времени в их Redux Devtools, поскольку вы перемещаете различные маршруты.

Теперь все это невозможно без какой-то более глубокой интеграции между реагированным маршрутизатором и Redux.

Итак, как это можно сделать?

Учитывая более глубокую интеграцию между React-Router и Redux

В прошлом React-Router предлагал библиотеку, React-Router-Redux Для этого. Однако на момент написания проект был устарел и больше не поддерживается.

Проект устарел, как видно на React-Router-Redux GitHub Repo .

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

Есть еще хорошие новости, как рекомендации React – Redux Redux, которые вы используете библиотеку, подключенный-реагирующий маршрутизатор

У него есть немного установки для использования, но это не так, если вам нужно преимущества.

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

Интеграция подключенного реагирования на эмозиланд

Первый набор вещей, которые нужно сделать, есть с магазином Redux.

1. Создать историю объекта

Технически, есть объект истории DOM для манипулирования сеансом истории браузера.

Давайте программно создадим один сами.

Чтобы сделать это, импортируйте CreateBrowserHistory из истории

В магазине/index.js:

...
import { createBrowserHistory } from 'history' 
...

История – это зависимость пакета React-Router-DOM, и он, вероятно, уже установлен при использовании React-Router в вашем приложении.

После импорта CreateBrowserHistory создайте объект истории, как это:

..
const history = createBrowserHistory()

Все еще в файле магазина/index.js.

До сих пор магазин был создан очень просто, как это:

const store = createStore(reducer);

Там, где редуктор относится к функции редуктора в редукторах/index.js, но это не будет очень в ближайшее время.

2. Оберните корневой редуктор

Импортируйте следующую функцию помощника в библиотеке подключенного реагирования-маршрутизации

import { connectRouter } from 'connected-react-router'

Коренный редуктор теперь должен быть завернут, как показано ниже:

const store = createStore(connectRouter(history)(reducer));

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

Чтобы увидеть, как мы сделали, есть до сих пор, в Index.js я экспортировал магазин Redux глобально, как это:

window.store = store;

Теперь в консоли браузера вы можете проверить, что в объекте состояния Redux с Store.getState ()

Вот что в действии:

Глядя в консоль Dev для маршрутизатор поле сейчас в состоянии redux

Как видите, в магазине Redux теперь есть поле маршрутизатора! Этот поле маршрутизатора всегда будет иметь информацию о текущем маршруте через объект местоположения E.G PathName, State и т. Д.

Мы еще не сделали.

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

Это объяснено дальше

3. Включая пользовательское промежуточное программное обеспечение

Чтобы включить пользовательское промежуточное программное обеспечение для обработки отправленных действий, импортируйте необходимые промежуточные программы RouterMidDleware из библиотеки:

...
import { connectRouter, routerMiddleware } from 'connected-react-router'

Затем используйте функцию ApplyMiddleware из Redux:

... 
import { createStore, applyMiddleware } from "redux";
... 
const store = createStore(
  connectRouter(history)(reducer),
applyMiddleware(routerMiddleware(history))
);

Теперь мы почти закончили. Всего еще один шаг.

4. Используйте подключенный маршрутизатор!

Помните, что React-redux дает нам компонент маршрута. Тем не менее, нам нужно обернуть эти компоненты маршрута в компоненте ondingRouter из библиотеки подключенного реагирования-маршрутизатора.

Вот как:

Во-первых, в Index.js вы импортируете компонент ondentRouter.

import { ConnectedRouter } from 'connected-react-router' 
...

Вот функция рендеринга файла index.js:

render(
  
    
  ,
  document.getElementById("root")
);

Помните, что приложение оказывает различные маршруты в приложении.

const App = () => (
  
    
      
      
      
      
      
      
    
  
);

Теперь, в index.js, оберните компонент приложения со компонентом ondingRouter. Компонент ConnectionRouter должен быть помещен в секунду только к компоненту поставщика из React-Router

Вот что я имею в виду:

render(
  
 
      

  ,
  document.getElementById("root")
);

Еще кое-что!

Прямо сейчас приложение не будет работать должным образом, поскольку stningRouter требует от one one one i.e История, который мы создали ранее.

Приложение теперь бросает эту ошибку:(

Поскольку нам нужен тот же объект в более чем в одном месте, нам нужно это как экспортируемый модуль.

Быстрое исправление – создать новый файловый магазин/History.js

import { createBrowserHistory } from "history";
const history = createBrowserHistory();
export default history;

Теперь этот экспортируемый объект истории будет использоваться в обоих местах, где это необходимо.

В index.js он импортируется так:

import history from "./store/history";

А затем передается в компонент ondentRouter, как показано ниже:

render(
  
    
      
    
  ,
  document.getElementById("root")
);

С этим установлена установка, а приложение работает – без нагрузочных ошибок мы видели раньше!

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

Есть больше, вы можете сделать с библиотекой подключенного реагирования-маршрутизатора, и большинство из них документируются В официальных часто задаваемых вопросах Отказ Кроме того, если у вас есть более надежный настроен с redux devtools, и промежуточное программное обеспечение регистратора, обязательно воспользуйтесь временными путешествиями и регистратором действий!

Заключение

Я надеюсь, что это было так же весело, как и для меня!

Если у вас есть какие-либо вопросы, обязательно бросьте их в раздел комментариев, и я буду рад помочь.

Иди построить что-то потрясающее, и я поймаю тебя позже!

Plug: Logrocket, DVR для веб-приложений

https://logrocket.com/signup/

Logrocket Это инструмент для ведения журнала Frontend, который позволяет вам повторить проблемы, как если бы они произошли в вашем браузере. Вместо того, чтобы угадать, почему случаются ошибки, или просят пользователей на скриншоты и журнал свалки, Lognocket позволяет воспроизвести сеанс, чтобы быстро понять, что пошло не так. Он отлично работает с любым приложением, независимо от структуры и имеет плагины для регистрации дополнительного контекста из Redux, Vuex и @ngrx. /хранить.

В дополнение к регистрации действий и состояния Redux, Lognocket Records Console Logs, ошибки JavaScript, Stacktraces, Networks/Ответы с заголовками + тел, метаданные браузера и пользовательские журналы. Он также привлекает инструменты DOM для записи HTML и CSS на странице, воссоздая Pixel-Perfect видео даже самых сложных приложений для одной страницы.

Попробуйте бесплатно.

Пост Завоевание навигационного состояния с React-Router и Redux появился первым на Logocket blog Отказ

Оригинал: “https://dev.to/bnevilleoneill/conquer-navigation-state-with-react-router-and-redux-2iaa”