我在next-url-prettifier上构建了该模块以启用命令式路由(程序包中通常不支持)。看起来像这样:
const ImperativeRouter = {
push: (path, query, shallow) => {
if (typeof window.location !== 'undefined') { // << THIS IS THE ISSUE
NextRouter.push(
{
pathname: `/${path}`,
query: query
},
Router.linkPage(path, query).as,
{ shallow }
)
}
}
}
我以前从未遇到过任何问题。您可以查看this github issue,其中的软件包维护者帮助我弄清楚了如何使其工作。
不过,我目前正在研究一个项目,该项目正在使用滚动劫持机制通过redux触发命令性的路线更改,并且出现了错误:
No router instance found.
You should only use "next/router" inside the client side of your app.
这就是为什么我在第一个代码示例中注释过的if(<!IS_SSR>)
(全局变量)块中写的原因。
我的减速器看起来像:
...
case TRANSITION_ROUTE: {
const { prevTrigger, prevRoute, nextRoute } = action.payload
prevTrigger
? ImperativeRouter.push(prevRoute.page, prevRoute.ops || { title: '' }, false)
: ImperativeRouter.push(nextRoute.page, nextRoute.ops || { title: '' }, false)
const newState = { ...state }
newState.transitionDirection = prevTrigger ? BACK : FORWARD
return IS_SSR ? state : newState
...
我设置了以下笑话测试用例:
describe('Router Reducer', () => {
describe('when invoking an imperative route transition', () => {
it('can transition to the previous page', () => {
console.log('IS SSR: ', IS_SSR)
const payload = {
prevTrigger: true,
nextTrigger: false,
prevRoute: routes[0],
nextRoute: routes[2]
}
if (!IS_SSR) {
expect(window.location.pathname).toEqual(payload.prevRoute.prettyUrl)
expect(routerReducer(initialState, { type: TRANSITION_ROUTE, payload })).toEqual({ ...initialState, transitionDirection: BACK })
} else {
expect(window.location.pathname).toEqual(routes[1].prettyUrl)
expect(routerReducer(initialState, { type: TRANSITION_ROUTE, payload })).toEqual(initialState)
}
})
it('can transition to the next page', () => {
console.log('IS SSR: ', IS_SSR)
const payload = {
prevTrigger: false,
nextTrigger: true,
prevRoute: routes[0],
nextRoute: routes[2]
}
if (!IS_SSR) {
expect(window.location.pathname).toEqual(payload.nextRoute.prettyUrl)
expect(routerReducer(initialState, { type: TRANSITION_ROUTE, payload })).toEqual({ ...initialState, transitionDirection: FORWARD })
} else {
expect(window.location.pathname).toEqual(routes[1].prettyUrl)
expect(routerReducer(initialState, { type: TRANSITION_ROUTE, payload })).toEqual(initialState)
}
})
})
})
...我认为它将解决问题,但是很奇怪,第一个测试can transition to previous page
通过了,但是第二个测试...next page
没有通过。
测试日志如下:
Router Reducer
when invoking an imperative route transition
✓ can transition to the previous page (2ms)
✕ can transition to the next page (4ms)
upon route transition
✓ sets the context for previous & next routes based on current route position in sitemap (1ms)
● Router Reducer › when invoking an imperative route transition › can transition to the next page
expect(received).toEqual(expected)
Expected value to equal:
"/work"
Received:
"/"
51 |
52 | if (!IS_SSR) {
> 53 | expect(window.location.pathname).toEqual(payload.nextRoute.prettyUrl)
54 | expect(routerReducer(initialState, { type: TRANSITION_ROUTE, payload })).toEqual({ ...initialState, transitionDirection: FORWARD })
55 | } else {
56 | expect(window.location.pathname).toEqual(routes[1].prettyUrl)
at Object.toEqual (__tests__/__redux__/routerReducer.test.js:53:42)
console.log __tests__/__redux__/routerReducer.test.js:22
IS SSR: false
console.warn server/router/ImperativeRouter.js:21
can only use next/router on clientside
console.log __tests__/__redux__/routerReducer.test.js:41
IS SSR: false
...显示出虽然显然在客户端上呈现了全局环境,但路由器显然无法正常工作(日志console.warn server/router/ImperativeRouter.js:21
can only use next/router on clientside
),并且根据失败的测试,其行为与预期不符
任何有思想的互联网人吗?