У меня есть пара кнопок, которые действуют как маршруты. Каждый раз при изменении маршрута я хочу убедиться, что активная кнопка меняется.
Есть ли способ прослушать изменения маршрута в реакции маршрутизатора v4?
react-router-v4
Kasper
источник
источник
Ответы:
Я использую ,
withRouter
чтобы получитьlocation
опору. Когда компонент обновляется из-за нового маршрута, я проверяю, изменилось ли значение:Надеюсь, поможет
источник
withRouter
, но получаю ошибкуYou should not use <Route> or withRouter() outside a <Router>
. Я не вижу ни одного<Router/>
компонента в приведенном выше коде. Так как это работает?<Switch>
компонент действует как де-факто маршрутизатор.<Route>
Будет отображена только первая запись с совпадающим путем. В<Router/>
этом сценарии нет необходимости в каких-либо компонентахЧтобы расширить вышесказанное, вам нужно будет добраться до объекта истории. Если вы используете
BrowserRouter
, вы можете импортироватьwithRouter
и обернуть свой компонент компонентом более высокого порядка (HoC) , чтобы иметь доступ через реквизиты к свойствам и функциям объекта истории.Единственное, о чем следует помнить, это то, что withRouter и большинство других способов доступа к
history
к объекту, похоже, загрязняют свойства, поскольку они объект в нем.источник
withRoutes
вwithRouter
.history
а не переменнуюlisten
.Вам следует использовать history v4 lib.
Пример оттуда
источник
history.push
это срабатываетhistory.listen
. См. Пример использования базового URL-адреса в документации по истории v4 . Поскольку наhistory
самом деле это оболочка собственногоhistory
объекта браузера, она не ведет себя точно так же, как собственный объект.const unlisten = history.listen(myListener); unlisten();
withRouter
,history.listen
ИuseEffect
(React Ловушки) работает довольно хорошо вместе:Обратный вызов слушателя будет срабатывать каждый раз при изменении маршрута, а возврат для
history.listen
- это обработчик завершения работы, с которым хорошо работаетuseEffect
.источник
v5.1 представляет полезный хук
useLocation
https://reacttraining.com/blog/react-router-v5-1/#uselocation
источник
Cannot read property 'location' of undefined at useLocation
. Вы должны убедиться, что вызов useLocation () находится не в том же компоненте, который помещает маршрутизатор в дерево: см. ЗдесьС крючками:
Импорт и рендеринг как
<DebugHistory>
компонентисточник
с крючками
источник
источник
С помощью react Hooks я использую
useEffect
источник
В некоторых случаях вы можете использовать
render
атрибут вместоcomponent
, таким образом:Обратите внимание: если вы измените состояние в
onRouteChange
методе, это может вызвать ошибку «Превышена максимальная глубина обновления».источник
С помощью
useEffect
ловушки можно обнаруживать изменения маршрута без добавления слушателя.источник
Я только что разобрался с этой проблемой, поэтому добавлю свое решение в качестве дополнения к другим предоставленным ответам.
Проблема в том, что на
useEffect
самом деле это не работает так, как вы хотели бы, так как вызов запускается только после первого рендера, поэтому возникает нежелательная задержка.Если вы используете какой-нибудь менеджер состояний, такой как, например, redux, есть вероятность, что вы увидите мерцание на экране из-за длительного состояния в магазине.
Что вы действительно хотите, так это использовать,
useLayoutEffect
поскольку это срабатывает немедленно.Поэтому я написал небольшую служебную функцию, которую поместил в тот же каталог, что и мой маршрутизатор:
Который я называю из компонента HOC следующим образом:
path
это опора, которая передается вmatch
объекте при использованииwithRouter
.Я не совсем сторонник того, чтобы вручную слушать / отменять историю. Это просто имо.
источник