Next.js + Redux命令式路由(带有next-url-prettifier pkg)-SSR问题

时间:2018-10-10 21:13:24

标签: reactjs routing jestjs server-side next.js

我在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),并且根据失败的测试,其行为与预期不符

任何有思想的互联网人吗?

0 个答案:

没有答案