最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to pass pageProps in next.js from a child component to _app.js? - Stack Overflow

programmeradmin4浏览0评论

I'm working on a next.js app and my page layout is going through the following hierarchy:

  _app.js
     Page.js
         Header.js
         PageContent.js

I need to pass some parameters from PageContent to Header without using redux.

Inside _app.js I have the following:

class Main extends App {
  render() {
  const {
    Component,
    pageProps,
    apollo,
    router: { route }
  } = this.props;

 return (
  <ApolloProvider client={apollo}>
      <Page
        pathname={route.split("/")[1]}
        {...pageProps}
        localLinks={Component.LocalLinks}
        render={props => <Component {...props} />}
      />
   </ApolloProvider>
  );
 }
}

I'm assuming there should be a way to pass some propse (pageProps) from PageContent to _app and pass that down to Page and make them accessible to header. Is there a next.js specific trick here that I'm not familiar with?

I'm working on a next.js app and my page layout is going through the following hierarchy:

  _app.js
     Page.js
         Header.js
         PageContent.js

I need to pass some parameters from PageContent to Header without using redux.

Inside _app.js I have the following:

class Main extends App {
  render() {
  const {
    Component,
    pageProps,
    apollo,
    router: { route }
  } = this.props;

 return (
  <ApolloProvider client={apollo}>
      <Page
        pathname={route.split("/")[1]}
        {...pageProps}
        localLinks={Component.LocalLinks}
        render={props => <Component {...props} />}
      />
   </ApolloProvider>
  );
 }
}

I'm assuming there should be a way to pass some propse (pageProps) from PageContent to _app and pass that down to Page and make them accessible to header. Is there a next.js specific trick here that I'm not familiar with?

Share Improve this question asked Jan 10, 2020 at 1:43 Adam BoostaniAdam Boostani 6,23310 gold badges40 silver badges44 bronze badges 1
  • I am not familiar with next.js, but in React you can just lift the state up, so your children will have access to modify those props that could be shared between sibling ponents: reactjs/docs/lifting-state-up.html – Bruno Monteiro Commented Jan 10, 2020 at 2:04
Add a ment  | 

2 Answers 2

Reset to default 1

You can use context api or Parent container state (here Page ponent).

First Way -> Use context api

Second Way

  • make State on page ponent
  • pass StatemodifierFunction props to pageContent
  • then modify state by calling this StatemodifierFunction
  • then pass this state to Header Component

** Third way **

  • you can use react node also

Here's a full example with contexts (approach previously suggested in this other answer by slightly modifying https://github./vercel/next.js/tree/7df7c5e80515eea6745fd59e54d87e5ee709fe0c/examples/with-app-layout tested on Next.js 12.0.7 and React 17:

pages/_app.js

import React from 'react'

export const MyAppContext = React.createContext({
  n: 0,
  setN: undefined,
});

function Header(props) {
  return <div>n = { props.n }</div>
}

export default function App({ Component, pageProps }) {
  const [n, setN] = React.useState(0)
  return (
    <MyAppContext.Provider value={{n, setN}}>
      <Header n={n} />
      <Component {...pageProps} />
    </MyAppContext.Provider>
  )
}

pages/index.js

import { MyAppContext } from './_app.js'
import React from 'react'

export default function Home() {
  const {n, setN} = React.useContext(MyAppContext)
  React.useEffect(() => {
    setN(new Date().getTime())
  }, [])
  return <div>test</div>
}

package.json

{
  "name": "with-app-layout",
  "version": "1.0.0",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "12.0.7",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "license": "MIT"
}

and run with:

npm install
npm run dev

The useEffect is required otherwise you will get the error:

Cannot update a ponent (`App`) while rendering a different ponent (`Home`)

which is mentioned at: Cannot update a ponent while rendering a different ponent warning Basically you cannot call .set methods directly from render.

If it's something that depends only on the page and not props

The following works without contexts, I wonder if setting such attributes could cause any problems down the line:

pages/_app.js

function Header(props) {
  return <div>n = { props.n }</div>
}

export default function App({ Component, pageProps }) {
  return (
    <>
      <Header n={Component.n} />
      <Component {...pageProps} />
    </>
  )
}

pages/index.js

export default function Home() {
  return <div>test</div>
}
Home.n = 1
发布评论

评论列表(0)

  1. 暂无评论