简体   繁体   中英

Pass data (prop) from _app.js to getServerSideProps in a page - NextJS, latest version

I have a custom _app.js :

  const Layout = ({ children }) => (children);

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

    pageProps.baseUrl = 'some url';

    return (
      <Layout>
        <Component {...pageProps} />
      </Layout>
    )
};

And a page:

export async function getServerSideProps({ req, query, res, baseUrl }) { 
// baseUrl is undefined and an error, if I am using it with destructiring

  console.log(req) // There is no baseUrl

  return { props: { ..... } }
}

I want to set that pageProps.baseUrl= 'some url'; in _app.js and use it in page components including getServerSideProps , how can I do that?

For now, I have created a file, which contains all global values like this:

let store = {};

const globalStore = {};

globalStore.set = (key, value) => {
    store = { ...store, [key]: value };
}

globalStore.get = (key) => {
    return store[key];
}


export default globalStore;

Then in _app.js import it and set a value:

const app = ({ Component, pageProps }) => {
    globalStore.set('baseUrl', 'some url 1');
    globalStore.set('baseUrl2', 'some url 2');

    return (
        <Layout>
            <Component {...pageProps} />
        </Layout>
    )
}

import the file in pages/index.js and inside the component or getServerSideProps :

export async function getServerSideProps({ req, query, res }) {

    console.log('in getServerSideProps');
    console.log(globalStore.get('baseUrl'));
    console.log(globalStore.get('baseUrl2'));
...

I think, in this particular case, it's ok to use constants here instead of props.

Proposed solution

In constants.js:

export const BASE_URL = 'some url';

And in your page:

import * as Constants from '../path/to/constants';

export async function getServerSideProps({ req, query, res }) { 
  // use Constants.BASE_URL here

  return { props: { ..... } }
}

Why won't props work the way you want them to?

Your page component and the getServerSideProps method you export from the file are separate, and are executed at different times. Rendering your component does not call getServerSideProps. I believe the order in Next.js is like this:

  1. A request is made at a route.
  2. Next.js looks at the file in pages/ for the corresponding route
  3. Next.js will run the appropriate method based on the execution context (on a server render, getServerSideProps)
  4. Next.js renders the App component, passing it the pageProps provided from getServerSideProps
  5. The App component renders the Page component

In this case, you have created a paradox. Think about how the props flow:

  1. getServerSideProps runs, returns a pageProps object
  2. App component renders, containing the pageProps object passed from getServerSideProps
  3. Page component renders, passed the pageProps

If getServerSideProps is responsible for creating the pageProps object, it can't also be passed that object as an argument.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM