5

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

4

3 回答 3

7

EDIT: I had to turn back to the global Router. The useRouter hook does not work, since its life cycle seems to be different and thus I cannot grab the exact values that I need at the given times.

.....
    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 };
};

EDIT: Since the global Router object pollution is not a nice thing to do, you could use a state variable instead:

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;

You have to use the hook in your _app.js since you listen for route changes and want to save/access the previousRoute globally.

const MyApp = ({ Component, pageProps }) => {

  const { previousRoute } = useRouteUrlHistory();

  return (
        <ApplicationContext.Provider
          value={{
            previousRoute,
            ... another global context
          }}
        >
           ... components etc.
        </ApplicationContext.Provider>

=====

I have not found an elegant way to be able to access Router.history in its entirety. But often enough I wanted to access at least the last visited route, which forced me to this workaround. It might not be the most elegant way since it pollutes the global Router object, but as I said I have not found any alternative.

I only check for the actual route which was visited previously. You may also implement your logic to check the params. The hook plugs-in before the Router handles the actual Route change. Which allows you to listen to the Router.previousRoute property within you application.

KEEP IN MIND if you do shallow Routing you may not affect the Router.history, which will probably not trigger this event hook.

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;
于 2021-01-07T14:28:31.793 回答
5

next/router不会像以前那样为您提供历史记录react-dom-router,它会在组件的props.

这是官方的使用示例

import { useRouter } from 'next/router'

const Post = () => {
  const router = useRouter()
  const { pid } = router.query

  return <p>Post: {pid}</p>
}

export default Post

如果你想推路由,你可以关注这个。例子

import Router from 'next/router'

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

export default ReadMore
于 2019-07-07T12:11:17.087 回答
2

您也可以使用路由器

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

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

路由器 API

于 2020-03-11T09:56:42.807 回答