1

GraphQL queries in my components are not running on dynamic routes when I try to access the query string with router.query.xxx.

I have the following file

// ./pages/section/[slug].js
import { useRouter } from 'next/router';
import AppLayout from '../../components/styles/_AppLayout';

const Section = () => {
  const router = useRouter();
  return <AppLayout>Hi</AppLayout>;
};

export default Section;

The page displays fine, but as soon as I add {router.query.slug} and refresh the page, it gives me a TypeError because the GraphQL queries do not run. As you can see in the image below, me.firstName is undefined because the GraphQL query did not run

TypeError_1.jpg

This is the code in _AppLayout.js

import styled from 'styled-components';
import Navigation from '../Navigation';
const Wrapper = styled.div`...`;
const AppLayout = props => {
  return (
    <Wrapper>
      <Navigation />
      <main>{props.children}</main>
    </Wrapper>
  );
};
export default AppLayout;

Any ideas why this might be happening and how to fix it?

Thanks

esausilva
  • 1,964
  • 4
  • 26
  • 54
  • your "me" object is null or empty which is why you are getting the error. Try to console.log(me) before you render and see if everything you need are available in the object "me" – Muljayan Aug 02 '19 at 03:38

2 Answers2

2

I was able to solve my issue two ways

Using withRouter

import { withRouter } from 'next/router';
import TestComponent from '../../components/TestComponent';
import AppLayout from '../../components/styles/_AppLayout';
const Section = props => {
  return <AppLayout>Hi {props.query.slug}</AppLayout>;
};
export default withRouter(Section);

and passing the query parameter as props via getInitialProps

const Section = ({slug}) => {
  return <AppLayout>Hi {slug}</AppLayout>;
};
Section.getInitialProps = async ({ query }) => {
  const { slug } = query;
  return { slug };
};
export default Section;
esausilva
  • 1,964
  • 4
  • 26
  • 54
0

The following method worked for me, I am using React Hooks with Context and I need to also use the nextJS route with it, so following configuration can be followed.

Note: If you are using GraphQL then that can be also wrapped around the final JSX in _app.js

_app.js:

import { withRouter } from "next/router";

BuilderProvider is here Context Provider

   const InjectRouterContext = withRouter(({ router, children }) => {
      return <BuilderProvider value={router}>{children}</BuilderProvider>;
    });


class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props;
    return (
      <InjectRouterContext>
        <ApolloProvider client={client}>
          <Component {...pageProps} />
        </ApolloProvider>
      </InjectRouterContext>
    );
  }
}

Now in the Page, here it is somepage.js:

import { useRouter } from "next/router";

    const somepage = () => {

      const router = useRouter();
      const { id } = router.query;

    return (//JSX Here);
    }

    somepage.getInitialProps = async ({ query }) => {
      const { slug } = query;
      return { slug };
    };
    export default somepage;
Ank
  • 402
  • 5
  • 12