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

Redux-первый роутер – шаг за пределы Redux-Little-маршрутизатор

Бесшовные Redux – первая маршрутизация – просто отправка акций

Автор оригинала: James Gillmore.

Проверьте Redux-первый маршрутизатор на GitHub

Цель Redux-первый маршрутизатор это подумать о вашем приложении в Государства , не маршруты , не Компоненты , сохраняя адресную строку в синхронизации. Все это состояние, а не компоненты. Подключите свои компоненты и просто отправка Флюс стандартные действия.

Redux – первый маршрутизатор – это то, что должно было существовать давно, но потому что это сообщество реагирования в то время, когда было выпущено выброшено столько древней мудрости, было пропущено. Redux – первый маршрутизатор завершает триэйумверрировать MVC, добавив «C» в уравнение (где redux – это «M» и реагирует «V»). По сути, это было так, как будто никто не хотел услышать буквы MVC снова. Это тоже для меня анафема, но это нужно, чтобы все же существовали.

RFR также убивает «все – это компонент», когда речь идет о маршрутах. Сейчас правильно: «Все состояние» и маршруты находятся на 100% в синхронизации с действиями, чтобы вызвать это состояние; Ваш просмотр слоя (компоненты) просто представляют от состояния, как они должны.

Прочитайте эти статьи, которые будут доведены до скорости

Мышление

Мышление позади Redux-первый маршрутизатор Был: «Если бы мы будем мечтать о подходе« redux-первый »к маршрутизации с нуля, что бы он выглядел?» Результатом было то, что мы надеемся, что вы считаете одним из этих сценариев «Инверсия контроля», которые делают сложную проблему простой При приеме на него от другого угла. Мы надеемся, что Redux-первый маршрутизатор выходит как очевидный раствор.

Демонстрация

Чтобы оформить заказ демонстрацию, прямо сейчас, у вас есть 2 варианта

Какая маршрутизация в redux предназначена для

Основная мотивация Redux-First-Router – это уметь использовать redux Как есть Удерживая URL в адресной строке в синхронизации. Другими словами, думать исключительно с точки зрения «Государство» и Не маршруты, пути, маршрутные компоненты Отказ И, конечно же для рендеринга бокового сервера, чтобы потребовать не более чем отправлять в магазине, как обычно. Пасические параметры – это просто полезные нагрузки действий, а типы действий дегранитят определенный вид пути Отказ То есть то, что маршрутизация в Redux предназначена для того, чтобы быть.

На практике то, что это означает, что обновление адресной строки в ответ на действия и двунаправленно Наличие действий, отправленные в ответ на изменения адреса, например, через кнопки Back/Wester/Forward. «Двунаправленный» аспект воплощен на диаграмме выше, где первые синие стрелки указывают в оба пути – то есть. Диспетчерские действия меняют адресную строку, и Изменения в адресной строке распределительные действия.

Кроме того, вот некоторые ключевые препятствия Redux-первый маршрутизатор ищет избегать :

  • необходимость рендеринга из любого состояния, которое не приходит из Redux
  • Заключить код компонента с компонентами, связанными с маршрутом
  • Добавленная сложность [и ошибки] из 2 форм состояния: состояние Redux против маршрутизации
  • Большие площадки поверхности API пакетов/каркасов, таких как Реагистрационный маршрутизатор и next.js.
  • обходные пути, которые такие крупные (Вероятно, «утечка») абстракции неизбежно требуют для достижения профессионального приложения
  • Стратегии как можно больше, чтобы справиться с анимацией. Анимации совпадают с обновлениями компонента реагирования являются Проблема, особенно в браузере (реакция на родом лучше). «Джанк» является общим. Техники, такие как должен быть необходим являются обязательными; Рамки для маршрутизации получают на пути оптимизации анимации.

Гист

Это Установить и-забудьте – это Так вот вот самая работа, которую вы когда-либо делаете!

import { connectRoutes } from 'redux-first-router'
import { combineReducers, createStore, applyMiddleware, compose } from 'redux'
import createHistory from 'history/createBrowserHistory'
import userIdReducer from './reducers/userIdReducer'

const history = createHistory()

// THE WORK:
const routesMap = { 
  HOME: '/home',      // action <-> url path
  USER: '/user/:id',  // :id is a dynamic segment
}

const { reducer, middleware, enhancer } = connectRoutes(history, routesMap) // yes, 3 redux aspects

// and you already know how the story ends:
const rootReducer = combineReducers({ location: reducer, userId: userIdReducer })
const middlewares = applyMiddleware(middleware)
const store = createStore(rootReducer, compose(enhancer, middlewares))
import { NOT_FOUND } from 'redux-first-router'

export const userIdReducer = (state = null, action = {}) => {
  switch(action.type) {
    case 'HOME':
    case NOT_FOUND:
      return null
    case 'USER':
      return action.payload.id
    default: 
      return state
  }
}

И вот как вы бы встроили SEO/Redux-Consers в вашем приложении, используя спусковое состояние:

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider, connect } from 'react-redux'
import Link from 'redux-first-router-link'
import store from './configureStore'

const App = ({ userId, onClick }) =>
  
{!userId ?

HOME

// all 3 "links" dispatch actions: User 123 // action updates location state + changes address bar User 456 // so does this User 5 // so does this, but without SEO benefits
:

USER: {userId}

// press the browser BACK button to go HOME :) }
const mapStateToProps = ({ userId }) => ({ userId }) const mapDispatchToProps = (dispatch) => ({ onClick: () => dispatch({ type: 'USER', payload: { id: 5 } }) }) const AppContainer = connect(mapStateToProps, mapDispatchToProps)(App) ReactDOM.render( , document.getElementById('react-root') )

Примечание. Все три кликабелистые элементы/ссылки выше будут изменять адресную строку во время рассылки соответствующего Пользователь действие. Единственное отличие – последний не получит преимущества SEO – I.E. Тег с совпадением к Путь не будет встроен на страницу. Что это значит, что вы можете принять существующее приложение Redux, которое отправляет подобные действия и получите преимущество синхронизации вашей адресной строки, не изменив свой код! Рабочий процесс, который мы рекомендуем, это сначала сделать это, а затем, как только вам удобно, использовать наш Компонент, чтобы указать ваши намерения в Google. Наконец, мы рекомендуем использовать Действия Как ваш к PROP, так как он не женится с вами до данной структуры URL-адресов – вы всегда можете изменить его в одно место позже ( MarrosPlapplock объект)!

На основе вышеуказанного Маршрута ГАР Следующие действия будут отправлены, когда Соответствующий URL посещается, и наоборот эти URL-адреса появятся в адресной строке, когда действия с соответствующими Тип и параметры предоставляются В качестве клавиш в объекте полезной нагрузки:

<-> /дом {Тип: «Главная»}
<-> / user / 123 {Тип: «Пользователь», полезная нагрузка: {ID: 123}}
<-> / user / 456 {Тип: «Пользователь», полезная нагрузка: {ID: 456}}
<-> / user / 5 {Тип: «Пользователь», полезная нагрузка: {ID: 6}}}

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

Наконец, мы не упомянули Redux-First-Router-Link И все же … Redux-первый маршрутизатор намеренно построен очень модульным способом, поэтому Компонент находится в отдельном пакете. Это очень просто, и вы можете сделать свой собственный. В основном это проходит к путь к Redux-первый маршрутизатор и звонки Event.PreventDefault () Чтобы остановить страницу перезагрузки. Это также может принять объект действий как опоры, который он преобразует в URL для вас! Его реквизиты API зеркала реагируют маршрутизатор. Пакет достаточно очевиден, когда вы получите повешение того, что происходит здесь – проверьте его, когда будете готовы: Redux-First-Router-Link Отказ И если вам интересно, да есть Navlink Компонент с реквизитом, как ActiveClass и ActiveStyle Как и в реактивный маршрутизатор.

Маршрута

Маршрута ГАР Объект позволяет сопоставить типы действий для экспресс-стиля динамических путей, с несколькими излишками. Вот основной (и очень минимальный легко запомнить ) Набор вариантов конфигурации, доступных для вас:

const routesMap = {
  HOME: '/home', // plain path strings or route objects can be used
  CATEGORY: { path: '/category/:cat', capitalizedWords: true },
  USER: { 
    path: '/user/:cat/:name',
    fromPath: path => capitalizeWords(path.replace(/-/g, ' ')),
    toPath: value => value.toLowerCase().replace(/ /g, '-'),
  },
}

Примечание: подпись упущение а также топатт предлагает немного больше, например: (Путьмент, ключ) => значение Отказ Посещение Маршрутные документы Для немного больше информации, когда придет время.

<-> /дом {Тип: «Главная»}
<-> / категория / JavaScript {Тип: «Категория», полезная нагрузка: {CAT: ‘JavaScript’}}
<-> / user / elm / evan-czaplicki {Тип: «Пользователь», полезная нагрузка: {CAT: ‘ELM’, Имя: ‘Evan czaplicki’}}

Маршрута (с Thunk)

Мы покинули одну конечную клавишу конфигурации: Thunk Отказ После отправки подходящего действия будет вызываться TUNK (если предоставлена), позволяющее извлечь параметры пути из состояния редуктора местоположения и внести асинронные запросы, чтобы получить необходимые данные:

const userThunk = async (dispatch, getState) => {
  const { slug } = getState().location.payload
  const data = await fetch(`/api/user/${slug}`)
  const user = await data.json()
  const action = { type: 'USER_FOUND', payload: { user } }
  
  dispatch(action)
}

const routesMap = {
  USER: { path: '/user/:slug', thunk: userThunk  },
}

Ваш Thunk следует вернуть обещание для SSR, чтобы иметь возможность ждать для его разрешения и для UpdatesCrels () быть вызванным, если использовать наши Пакет восстановления прокрутки Отказ

Примечание: посетите Документы редуктора местоположения чтобы увидеть место расположения Форма штата

<-> / user / stive-jobs {Тип: «Пользователь», полезная нагрузка: {Slug: ‘Стива-Работа’}}
N / A. N / A. {Type: ‘user_found’, Payload: {Пользователь: {Название: ‘Стив Джобс’, Slug: ‘Стива-Работа’}}}

Это все люди!

Убедитесь, что Zere Reppo здесь: github.com/faceyspacey/redux-first-router.

Дополнительная информация