4
votes

It doesn't seem like this question has been asked before for Next.js and some googling didn't really provide an answer. It's been asked specifically for React but in the Next.js framework I don't think the solution I've been using will work.

My app is basically a shop and I have a nav menu in the Layout component that wraps the app. There's Basket item in the Layout component (showing number of items) and then I have a Details component page from where I can add items to the basket.

I appreciate that it might go against the paradigm of using React (and particularly) Next.js but in the past I have solved the problem (in React and React-Router) of a child having to update the state of the parent by passing down function handlers via the props of a child. For simple applications this has often done the trick for me and solved the issue quickly.

In next JS, since I never specifically initialise the child component (Detatils page), how do I call functions of the parent component (Layout, that wraps my entire app) ?

Is this impossible without using server-side state and/or redux?

function MyApp({ Component, pageProps }) {
  return (
    <Layout> {*this contains the basket icon with the number of items*}
        <Component {...pageProps} />
    </Layout>   
  )
}

export default MyApp

UPDATE

I ended up using React's useContext hook to do this, registering variables function handlers to a global app context. I'm not sure if this is an antipattern or ruining the point of using Netx.js.... we'll see...

1
you can refer to this response, that answer to a similar question stackoverflow.com/questions/63911883/… that explain how to implement a global context - dna
Half a year in - does the design hold? was it an antipattern? Tnx - Oded Ben Dov

1 Answers

1
votes

It seems no way to get the function from Layout component in a specific page without using server-side state or redux.

Basically, if you want to execute the function both in Layout and a specific page, I think the right way is move the function out over the Layout and the page. As a result, define the function in _app.js.

function MyApp({ Component, pageProps }) {
    function layoutFn() {
        console.log('Execute layoutFn')
    }

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

export default MyApp

However, I think it is more reasonable to define the global function in redux and execute it in Layout or page by using dispatch.