In the React context, when building an app I'm used to the concept of containers and components. It appears to me that "pages" are somewhat equivalent to containers within next.js.
Is there a recommended way to add an application layout container such that I could specify for example global <Header/>
and <Footer/>
components with the router determining which content to display within (the page)? Similar to how the popular react-router
package match
function can be configured on the server.
Using the next.js default router and pages folder as is, to achieve this do I have no option but to duplicate <Header/>
and <Footer/>
across all pages?
Just an idea: you may consider to write an higher order component that takes your page component and returns some structure like this
<section>
<Header />
<YourPageComponent />
<Footer />
</section>
Update:
components/AppLayout.js
import React, { Component } from 'react';
import { Header, Footer } from 'components';
const withAppLayout = () => (ComposedComponent) => {
class AppLayout extends Component {
render() {
return (
<section>
<Header />
<ComposedComponent {...this.props} />
<Footer />
</section>
);
}
}
return AppLayout;
};
export default withAppLayout;
pages/index.js
import withAppLayout from 'components/AppLayout';
const Home = () => (<div>Home</div>);
export default withAppLayout(Home);
Thank you for your reply 馃槂 .
Where would I specify this HOC in the context of next.js though?
The default router will render index.js
for /
and about.js
for /about
. Do I have to duplicate for both?
index.js
export default () => (
<div><Header/>Home<Footer/></div>
)
about.js
export default () => (
<div><Header/>About<Footer/></div>
)
@davidrossjones one option is:
// components/Layout.js
export default () => (
<div>
<h1>Header</h1>
{this.props.children}
<footer>the footer</footer>
</div>
)
// pages/index.js
import Layout from '../components/Layout'
export default () => (
<Layout>
<p>Home</p>
</Layout>
)
// pages/about.js
import Layout from '../components/Layout'
export default () => (
<Layout>
<p>About</p>
</Layout>
)
Aha! That makes perfect sense.
Thank you @altayaydemir and @impronunciable for the insight! Awesome. 馃憤
@impronunciable @altayaydemir Apparently, the Layout wrapper component gets re-mounted when changing routes which does not completely solve the problem. @ericf describes this in #50.
@dlindenkreuz well, you are right. 馃槬 I also agree on having an app layout component.
how to get initial props using this layout? like this
static getInitialProps ({ req}) {
return {request: req ? 'Server' : 'Client '}
}
In the React context, when building an app I'm used to the concept of containers and components. It appears to me that "pages" are somewhat equivalent to containers within next.js.
I was wondering the same thing as well. Is there anything fundamentally different between pages and containers?
Wondering the same over here.
I was used more to.
./pages/Index.js
const IndexPage = ({ serverCall }) => (
<div>
<button onClick={serverCall}>Hello</button>
</div>
);
export default IndexPage;
And then on.
./containers/Index.is
import IndexPage from './pages/Index.js'
const composerData = (props, onData) => {
onData(null, {
serverCall: () => console.log('call');
})
};
export default compose(composerData)(IndexPage);
where compose can be something like https://github.com/arunoda/react-komposer, but still i'm not sure if this the correct usage for NextJs, or i can avoid the Container and do this on the Page directly
You could use pages/_app.js
for global layout now.
Most helpful comment
Just an idea: you may consider to write an higher order component that takes your page component and returns some structure like this
Update:
components/AppLayout.js
pages/index.js