NextJS - Passing client-side props from app.js to specific components

Viewed 58

In traditional React, a common pattern is to define the Routers at the entry point, and pass whatever props you need to whichever component needs them, since they're all defined

Eg,

<Switch>
  <Route exact path="/">
    <Home prop1={prop1}/>
  </Route>
  <Route path="/about">
    <About prop1={prop1} prop2={prop2}/>
  </Route>
  <Route path="/dashboard">
    <Dashboard />
  </Route>
</Switch>

It's not clear to me how to do this in NextJS. The entry point _app.js has a generic that's used for all components. What would be the best way to pass prop1 to Home and About, but not Dashboard?

To be clear, these are client-side props, not server-side or static props

2 Answers

You can use getStaticProps, see the code below:

export async function getStaticProps(context) {
   return {
   props: {}, // will be passed to the page component as props
   // export this function from each page you want to pass props, in your 
   // case have this function on About, Home and Dashboard pages.
  }
}

for more check this link: getStaticProps

You can pass page specific props in getServerSideProps like below

import { GetServerSideProps } from "next";

const PageA = () => {
}

export const getServerSideProps: GetServerSideProps = async (ctx) => {
    return {
        props: {
            forbidden: true
        }
    }
}

export default PageA;

Then you can control that prop value in _app.js file and take action

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

  if (pageProps.forbidden) {
    return <Page403 />;
  }

  return (
    <Provider store={store}>
       <Component {...pageProps} />
    </Provider>
  )

}

So, think reversely.

UPDATE

Okay, so you want _app.js to be your starting point. Here's a way to do so.

_app.js

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

  if (pageProps.forbidden) {
    return <Page403 />;
  }

  return (
    <Provider store={store}>
       {pageProps.forbidden ? <Component {...pageProps} /> : <Component {...pageProps} testProp={true} />}
    </Provider>
  )

}

In this technic, we still need to mark the pages we want that specific prop to be existed. For instance, we want that prop to be existed in pages which are not forbidden. Page A, in this case, should not get that prop.

import { GetServerSideProps } from "next";

const PageA = (props) => {
  console.log('PageA props', props);//we should not see testProp here
}

export const getServerSideProps: GetServerSideProps = async (ctx) => {
    return {
        props: {
            forbidden: true
        }
    }
}

export default PageA;

But Page B should get it.

import { GetServerSideProps } from "next";

const PageB = (props) => {
  console.log('PageB props', props);//we should see testProp here
}

export const getServerSideProps: GetServerSideProps = async (ctx) => {
    return {
        props: {}
    }
}

export default PageB;

You can modify the logic according to your needs.

Related