useRouter/withRouter receive undefined on query in first render

后端 未结 4 890
时光说笑
时光说笑 2021-01-05 15:01

I got a problem with my dynamic route. It look like this

[lang]/abc

I am trying to get query value from [lang] but when I using

相关标签:
4条回答
  • 2021-01-05 15:23

    It is not possible to get a query value at the first render.

    Statically optimized pages are hydrated without provided route parameters. E.g. query is an empty object ({}).

    After hydration, Next.js will fill the query object.

    Also, at first render of a dynamic route router.asPath and router.route are equal. Once query object is available, router.asPath reflects it.

    You can rely on the query value within a useEffect hook after asPath has been changed.

    const router = useRouter();
    
    useEffect(() => {
      if (router.asPath !== router.route) {
        // router.query.lang is defined
      }
    }, [router])
    

    GitHub Issue - Add a "ready" to Router returned by "useRouter"

    0 讨论(0)
  • 2021-01-05 15:32

    This is a good work, I found around from this comment

    Add useQuery.ts helper file

    // useQuery.js
    import { useRouter } from 'next/router';
    
    // Resolves query or returns null
    export default function useQuery() {
      const router = useRouter();
      const hasQueryParams =
        /\[.+\]/.test(router.route) || /\?./.test(router.asPath);
      const ready = !hasQueryParams || Object.keys(router.query).length > 0;
      if (!ready) return null;
      return router.query;
    }
    

    usage

    // In your components (instead of useRouter)
    const query = useQuery();
    
    useEffect(() => {
      if (!query) {
        return;
      }
      console.log('my query exists!!', query);
    }, [query]);
    
    0 讨论(0)
  • 2021-01-05 15:41

    In NextJS 9, one way to ensure route parameters are immediately available for page components is to get them from the context arg passed to getServerSideProps() and pass to the component as props.

    For a page like [id].js,

    export function getServerSideProps(context) {
      return {
        props: {params: context.params}
      };
    }
    
    export default ({params}) => {
      const {id} = params;
      return <div>You opened page with {id}</div>;
    };
    
    0 讨论(0)
  • 2021-01-05 15:44

    I resolved my problem that I need it in Hoc component. I wrapped using withRouter(withLocale(Comp)) and create conditional in HOC

    export default function withLocale(WrappedPage) {
        const WithLocale = ({ router, ...props }) => {
            const { lang } = router.query;
            if (!lang || !isLocale(lang)) {
                return <Error statusCode={404} />;
            }
            return (
                <LocaleProvider lang={lang}>
                    <WrappedPage {...props} />
                </LocaleProvider>
            );
        };
       return WithLocale;
    }
    
    0 讨论(0)
提交回复
热议问题