gpt4 book ai didi

javascript - Next.js 路由器中的多个事件监听器

转载 作者:行者123 更新时间:2023-11-30 14:59:21 25 4
gpt4 key购买 nike

目前 next/router 公开了一个单例 API,可以通过以下方式监听它的变化:

Router.onRouteChangeStart = myHandler // subscribe

Router.onRouteChangeStart = null // unsubscribe

这带来了几个与架构相关的挑战,因为两个不相关的组件无法同时监听路由状态变化。

基于关于 https://github.com/zeit/next.js/issues/2033 的讨论没有计划将 next/router 转换为 Event Emitter/Observable。

鉴于此,我们如何在 Next.js 中实现具有共享订阅的路由器?

最佳答案

到目前为止,我一直满意的解决方案包括在 Observables 中包装 next/router 监听器方法,并创建一个 HLA 将路由器事件附加到 componentDidMount 上的组件。

使用 RxJS 的示例实现:

// I'm using recompose 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 component subscribes to this observable

export const routeChangeComplete$ = Observable.create(
obs => {
Router.onRouteChangeComplete = () => {
console.log('route: complete')
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 component
import { lifecycle } from 'recompose'
import * as SharedRouter from './sharedRouter'

const withRouterEvents = lifecycle({
componentDidMount(){
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
]
},

componentWillUnmount(){
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>

关于javascript - Next.js 路由器中的多个事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46770364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com