【问题标题】:How to get history and match in this.props in nextjs?如何在 nextjs 的 this.props 中获取历史和匹配?
【发布时间】:2019-11-13 10:06:36
【问题描述】:

我想在 this.props 中获取历史值和匹配项。我正在使用next/router 导入withRouter。我想使用 this.props.match.params 获取 url 中的值并使用 history.push 进行重定向。如何在 Next.js 中得到这个。现在我没有在 this.props 中获得历史和匹配。

【问题讨论】:

    标签: next.js next-router


    【解决方案1】:

    编辑:我不得不转回全局路由器。 useRouter 钩子不起作用,因为它的生命周期似乎不同,因此我无法在给定时间获取我需要的确切值。

    .....
        if (
          !shallow &&
          !(EXCEPTIONS.includes(nextUrl) || EXCEPTIONS.includes(Router.asPath)) &&
          nextUrl !== Router.asPath
        ) {
          setPreviousRoute(Router.asPath);
        }
      };
    
      useEffect(() => {
        Router.events.on('beforeHistoryChange', handleBeforeHistoryChange);
    
        return () => {
          Router.events.off('beforeHistoryChange', handleBeforeHistoryChange);
        };
      }, []);
    
      return { previousRoute };
    };
    

    编辑:由于全局路由器对象污染不是一件好事,您可以改用状态变量:

    const EXCEPTIONS = ['/sign-up'];
    
    /**
     * Saves the current URL before changing the route.
     */
    const useRouteUrlHistory = () => {
      const [previousRoute, setPreviousRouter] = useState('');
      const router = useRouter();
    
      const handleBeforeHistoryChange = (url) => {
        const [nextUrl] = url?.split('?') || [];
    
        if (
          !(EXCEPTIONS.includes(nextUrl) || EXCEPTIONS.includes(router.asPath)) &&
          nextUrl !== router.asPath
        ) {
          setPreviousRouter(router.asPath);
        }
      };
    
      useEffect(() => {
        router.events.on('beforeHistoryChange', handleBeforeHistoryChange);
    
        return () => {
          router.events.off('beforeHistoryChange', handleBeforeHistoryChange);
        };
      }, []);
    
      return { previousRoute };
    };
    
    export default useRouteUrlHistory;
    

    您必须在 _app.js 中使用钩子,因为您监听路由更改并希望全局保存/访问 previousRoute。

    const MyApp = ({ Component, pageProps }) => {
    
      const { previousRoute } = useRouteUrlHistory();
    
      return (
            <ApplicationContext.Provider
              value={{
                previousRoute,
                ... another global context
              }}
            >
               ... components etc.
            </ApplicationContext.Provider>
    

    =====

    我还没有找到一种优雅的方式来访问 Router.history 的全部内容。但我经常想访问至少最后一次访问的路线,这迫使我采用这种解决方法。这可能不是最优雅的方式,因为它会污染全局 Router 对象,但正如我所说,我还没有找到任何替代方法。

    我只检查之前访问过的实际路线。您还可以实现您的逻辑来检查参数。 Router 处理实际 Route 更改之前的钩子插件。这允许您在应用程序中监听 Router.previousRoute 属性。

    请记住,如果您执行shallow Routing,您可能不会影响 Router.history,这可能不会触发此事件挂钩。

    const EXCEPTIONS = ['/sign-up'];
    
    /**
     * Saves the current URL before changing the route.
     * The previousRoute is then accessible via the global Router.
     */
    const useRouteUrlHistory = () => {
      const handleBeforeHistoryChange = (url) => {
        const [nextUrl] = url?.split('?') || [];
    
        if (
          !(EXCEPTIONS.includes(nextUrl) || EXCEPTIONS.includes(Router.asPath)) &&
          nextUrl !== Router.asPath
        ) {
          Router.previousRoute = Router.asPath;
        }
      };
    
      useEffect(() => {
        Router.events.on('beforeHistoryChange', handleBeforeHistoryChange);
    
        return () => {
          Router.events.off('beforeHistoryChange', handleBeforeHistoryChange);
        };
      }, []);
    };
    
    export default useRouteUrlHistory;
    

    【讨论】:

    • 你在哪里使用这个钩子,肯定它需要靠近应用根目录,也需要在想要访问路由历史记录的孩子中?
    • 没关系,在任何功能性反应组件中。这里的主要问题是我污染了 Router 对象,这与 NextJs useRouter 挂钩效果不佳。由于我使用来自 next-i18next 的自定义路由器,这不是一个特别的问题,因为路由器对象是全局可访问的。
    • 我已经编辑了示例以在 _app.js 中使用挂钩而不会受到路由器污染
    【解决方案2】:

    next/router 不会像 react-dom-router 那样为您提供历史记录,它会在组件的 props 中为您提供称为查询的东西。

    这是官方usage example

    import { useRouter } from 'next/router'
    
    const Post = () => {
      const router = useRouter()
      const { pid } = router.query
    
      return <p>Post: {pid}</p>
    }
    
    export default Post
    

    如果你想推路由,你可以关注这个。 example.

    import Router from 'next/router'
    
    function ReadMore() {
      return (
        <div>
          Click <span onClick={() => Router.push('/about')}>here</span> to read more
        </div>
      )
    }
    
    export default ReadMore
    

    【讨论】:

      【解决方案3】:

      你也可以使用路由器

      import Router from 'next/router'
      // on Submit handler
      Router.push(url)
      

      其中 url 是您要重定向到的页面。

      Router API

      【讨论】:

        猜你喜欢
        • 2016-08-05
        • 2019-07-17
        • 1970-01-01
        • 1970-01-01
        • 2019-07-26
        • 1970-01-01
        • 1970-01-01
        • 2021-01-17
        • 1970-01-01
        相关资源
        最近更新 更多