admin管理员组文章数量:1326345
Currently next/router
exposes a singleton API where listening to its changes can be done via:
Router.onRouteChangeStart = myHandler // subscribe
Router.onRouteChangeStart = null // unsubscribe
This poses several architecture-related challenges as two unrelated ponents can't listen to route state changes at the same time.
Based on the discussion on .js/issues/2033 there is no plan to convert next/router
to an Event Emitter / Observable.
Given that, how can we implement a router with shared subscriptions in Next.js?
Currently next/router
exposes a singleton API where listening to its changes can be done via:
Router.onRouteChangeStart = myHandler // subscribe
Router.onRouteChangeStart = null // unsubscribe
This poses several architecture-related challenges as two unrelated ponents can't listen to route state changes at the same time.
Based on the discussion on https://github./zeit/next.js/issues/2033 there is no plan to convert next/router
to an Event Emitter / Observable.
Given that, how can we implement a router with shared subscriptions in Next.js?
Share Improve this question asked Oct 16, 2017 at 12:29 Rafal PastuszakRafal Pastuszak 3,1602 gold badges31 silver badges31 bronze badges2 Answers
Reset to default 3The solution I've been happy with so far involves wrapping next/router
listener methods in Observables and creating a HLA attaching router events to ponents on ponentDidMount.
An example implementation using RxJS:
// I'm using repose for and rxjs, but you should be able to modify this code easily
// 1. sharedRouter.js
import Router from 'next/router'
import { Observable } from 'rxjs'
export const routeChangeStart$ = Observable.create(
obs => {
console.log('route: start')
Router.onRouteChangeStart = url => {
obs.next(url)
}
}
).share() // note the .share() operator,
// it ensures that we don't reassign Router.onRouteChangeStart
// every time a new ponent subscribes to this observable
export const routeChangeComplete$ = Observable.create(
obs => {
Router.onRouteChangeComplete = () => {
console.log('route: plete')
obs.next()
}
}
).share()
export const routeChangeError$ = Observable.create(
obs => {
Router.onRouteChangeError = () => {
console.log('route: error')
obs.next()
}
}
).share()
// 2. appBar/withRouterEvents.js
// This one is attached to our AppNav ponent
import { lifecycle } from 'repose'
import * as SharedRouter from './sharedRouter'
const withRouterEvents = lifecycle({
ponentDidMount(){
const onStartLoadingSub = Router.routeChangeStart$
.subscribe(
() => {
// hide nav
// show loading indicator
}
)
const onFinishLoadingSub = Router
.routeChangeError$
.merge(Router.routeChangeComplete$)
.subscribe(
() => {
// hide loading indicator
}
)
this.subs = [
onStartLoadingSub,
onFinishLoadingSub
]
},
ponentWillUnmount(){
if(!Array.isArray(this.subs)) return;
this.subs.forEach(
sub => sub.unsubscribe()
)
}
})
// 3. appBar/index.js
export default ({
isNavVisible,
isLoading,
children
}) => <nav className={
isNavVisible ? 'app-bar' : 'app-bar app-bar--hidden'
}>
<LoadingIndicator isActive={isLoading} />
{children}
</nav>
Good news! As from Version of Next.js 6.1.1
multiple router event listeners will be allowed:
Example
Router.events.on('routeChangeStart', (url) => {
console.log('App is changing to: ', url)
})
Docs
- Pull Request
- Documentation
本文标签: javascriptMultiple event listeners in Nextjs routerStack Overflow
版权声明:本文标题:javascript - Multiple event listeners in Next.js router - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742198978a2431602.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论