direct-react-router
Достоинства
- redux first → не зависит от жизненного цикла компонентов → нет сайд-эффектов в компонентах (например, больше не нужна генерация действий в
componentDidMount
) - настройки роутинга в одном месте → в конфиге плоский список роутов и алиасы для них
- алиасы вместо url → роутер парсит алиасы роутов в адресах и генерирует по алиасам правильные url → не нужно завязываться в коде на конкретные url (в т.ч. не нужны спец. компоненты для условного рендеринга)
- можно использовать по частям (например, только middleware) → расширяемость (например, можно использовать с
react-router
, а можно и не использовать 😋) - поддержка TypeScript из коробки
Как установить
npm i direct-react-router
Зависимости: react ^16.8.6
, redux ^4.0.1
, react-redux ^7.0.0
, history ^5.0.0
.
Как использовать
Конфигурация
Конфигурация задает плоский список роутов и алиасы для них. Также вам понадобится экземпляр history
.
;; ; ;
Синтакис шаблонов путей:
;
При сравнении всегда
exact === true
, поэтому порядок описания роутов не важен. Если текущему URL соответствует несколько роутов, будет исключение.
Middleware
;// ...;// ...;
Теперь при каждом изменении url будет генериироваться action, который вы можете обрабатывать любым нужным способом. В него приходит информация о новом URL и его параметрах + его alias в конфиге.
/*{ type: '@@direct-react-router/LOCATION_CHANGED', location: { key: '<route key>', pathname: '...', search: '...', hash: '...', params: { ... }, query: { ... } }, action: 'PUSH'}*/
Reducer + state
Вы можете подключить готовый редюсер, который будет обрабатывать события изменения URL и класть информацию в state. Также он отвечает за начальное состояние (начальный url).
; ;
Ссылки
;// ... render /*location: { pathname: '/p2/test/count/12', search: '?aa=1&bb=2', hash: '#xxx', key: 'PAGE2', params: { login: 'test', num: '12' }, query: { aa: '1', bb: '2' }}*/
Генерация ссылок по ключам
;// ... render /*href: /p2/test/count/12?aa=1&bb=2#xxxlocation: { pathname: '/p2/test/count/12', search: '?aa=1&bb=2', hash: '#xxx', key: 'PAGE2', params: { login: 'test', num: '12' }, query: { aa: '1', bb: '2' }}*/
Внимание! проверьте, что нет лишних перерисовок
History options
Через пропсы компонентов Link
и AdvancedLink
можно настраивать параметры обращения к history api:
replace?: boolean
- использоватьREPLACE
(по умолчаниюPUSH
)state?: object | null
- объект состояния, ассоциированный с новой записью истории браузераforceReload?: boolean
- перезагружать страницу при переходе по ссылке
Base path
Везде работаем с относительными путями.
- Для адресной строки — указать
basename
вcreateBrowserHistory
. - Для генерации ссылок — пробросить
basename
через контекст.
;// ...; // учитываем basename при обработке url; render /*href: /your/base/path/test/xxxlocation: { pathname: '/test/xxx', ...}*/
Генерировать action при открытии страницы
Middleware генерирует экшены при изменении url в адресной строке. При открытии страницы экшен с текущим url по умолчанию не генерируется. Если он вам нужен, сгенерируйте его руками.
;// ... ;store.dispatchchangeLocationrouterLocation;
todo
- импорт компонента ссылки из корня
- устанавливать начальный path
- location по умолчанию
- редюсер
- генерация ссылок по ключу????? (
откуда брать конфиг? как вариант, можно коннектить каждую ссылку к стору и складывать конфиг в сторконфиг передается через контекст) - обрубать
?
в query string - приоритет роутов - задаем в виде массива
- придумать, как задавать query string и hash для AdvancedLink
- exact
- base path
- атрибуты ссылки
- callHistoryMethod, который принимает RouteArgs + добавить параметр с названием методов
- выключать spa переходы через пропсы
- persistQuery
- переделать базовый компонент на HOC
- query-string options
подумать
- проверить, как ведет себя звездочка в роутах
- проверить, что приходит в action, если адрес - url encoded
- подумать, нужно ли кодировать hash при генерации url
- когда происходит отписка от событий history
License
MIT