简体   繁体   English

Next.js 选择退出 _app.js 中特定页面的布局组件

[英]Next.js Opt out of Layout Component for specific pages from _app.js

How to not wrap a specific page with Layout component in _app.js ?如何不在_app.js中使用Layout 组件包装特定页面?

For example, I have two pages as pages/home and pages/about , now how can I not wrap my pages/home page with Layout component?例如,我有两个页面pages/homepages/about ,现在如何不使用Layout组件包装我的pages/home页面?

pages/_app.js页面/_app.js

import "../styles/globals.css";
import Layout from "../components/Layout";

function MyApp({ Component, pageProps }) {

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

export default MyApp;

What I have tried:我试过的:

pages/_app.js页面/_app.js

function MyApp({ Component, pageProps }) {
  console.log(typeof Component); // gives me a function

  switch (Component) {
    case Home():
      return <Component {...pageProps} />;
    default:
      return (
        <Layout>
          <Component {...pageProps} />{" "}
        </Layout>
      );
  }
}

pages/home.js页面/home.js

import React from 'react';
 
const Home= () => {
  return (<div>Hello</div>);
};
 
export default Home;

by checking the appProps.router.pathname property passed to it.通过检查传递给它的appProps.router.pathname属性。

way 1方式1

function MyApp({ Component, pageProps, ...appProps }: AppProps) {
  const getContent = () => {
    if ([`/dashboard`].includes(appProps.router.pathname))
      return <Component {...pageProps} />;

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

  return <ApplicationWrapper>{getContent()}</ApplicationWrapper>;
}

way 2方式2

function MyApp({ Component, pageProps, ...appProps }: AppProps) {

    const isLayoutNeeded = [`/dashboard`].includes(appProps.router.pathname);

    const LayoutComponent = isLayoutNeeded ? Layout : React.Fragment;

    


  return (<ApplicationWrapper> 
    <LayoutComponent>
        <Component />
    </LayoutCompnent>
    </ApplicationWrapper>);
}

I think there is cleaner way of doing this withPer-Page Layouts .我认为使用Per-Page Layouts有更简洁的方法。 I'm currently doing this simple by creating a default layout for all pages and override it for the pages that require specific layout, for example in my login and registration pages.我目前正在通过为所有页面创建默认布局并为需要特定布局的页面(例如在我的登录和注册页面中)覆盖它来做到这一点。

    export default function LoginPage() {
      return {
        /** Some JSX */
      }
    }
    // Return the page without additional layout.
    LoginPage.getLayout = (page) => page

    export default function MyApp({ Component, pageProps }) {
      // Use the specified page layout or fallback to the default one.
      const getLayout = Component.getLayout ?? defaultPageLayout

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

I use displayName static property.我使用displayName static 属性。 It works in any React.js component as well.它也适用于任何 React.js 组件。

const OGImagePreview = () => <h1>OG Image Preview</h1>

OGImagePreview.displayName = 'OGImagePreview'

export default OGImagePreview

Then I use switch...case in _app.tsx like:然后我在_app.tsx中使用switch...case ,例如:

switch (Component.displayName) {
    case 'OGImagePreview':
        return (
            <>
                <Component {...pageProps} />
            </>
        )
    default:
        return (
            <>
                <Head>
                    <meta name="viewport" content="initial-scale=1.0, width=device-width" />
                </Head>
                <ThemeProvider attribute="class" themes={['light', 'dark']}>
                    <Progress />
                    <Nav />
                    <Component {...pageProps} />
                </ThemeProvider>
                <ScrollToTop />
                <Analytics />
            </>
        )
}

what about this?那这个呢? Hope can save someone希望能救人

 import "../styles/globals.css"; import dynamic from "next/dynamic"; const Layout = dynamic(() => import("@layout/Layout")); import { useRouter } from "next/router"; function MyApp({ Component, pageProps }) { const router = useRouter(); return ( <> {router.pathname?== "/". ( <Layout> <Component {..:pageProps} /> </Layout> ). ( <Component {..;pageProps} /> )} </> ); } export default MyApp;

You can simply leverage useRouter from 'next/router' and get your job done easily.您可以简单地利用“下一个/路由器”中的 useRouter 并轻松完成工作。

import {useRouter} from 'next/router';

function MyApp({ Component, pageProps }) {
  const router = useRouter();

  if(router.asPath =='/dashboard')  {
     return (
       <Component {...pageProps} />
     )
  }

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

What about using higher order components .使用高阶组件怎么样? They are not part of react API but as react docs says, "They are a pattern that emerges from React's compositional nature."它们不是 react API 的一部分,但正如 react docs 所说,“它们是从 React 的组合性质中出现的一种模式。” Next uses react so it does make sense to use react patterns in next Next 使用 react 所以在 next 中使用 react 模式是有意义的

The following code wraps a given component with a predefined Header and Footer component.以下代码使用预定义的HeaderFooter组件包装给定组件。 Then a component that uses it is wrapped with the HOC when exported然后使用它的组件在导出时用 HOC 包装

    const withLayout = Comp =>  {
        const WrappedComp = (props) => {
            return (
                <div id='layout'>
                    <Header />
                    <Comp {...props} />
                    <Footer />
                </div>
            );
        }
        return WrappedComp;
    }

    const Section = () => {
        return ( 
            <section>
                Section content...
            </section>
        );
    }

    export default withLayout(Section);

I have tried my code in this way and its working fine for me.我已经以这种方式尝试了我的代码,并且它对我来说工作正常。

`
    import { useRouter } from "next/router";
    function MyApp({ Component, pageProps}: AppProps) {
      const router = useRouter();
      return (
        <>
          {router.pathname !== "/contact" ? (
            <>
              <NavBar />
              <Component {...pageProps} />
              <JoinUsSection />
              <Footer />
            </>
          ) : (
            <>
              <NavBar />
              <Component {...pageProps} />
              <Footer />
            </>
          )}
        </>
      );

}`

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Next.js - Eslint 不会在开发模式下对任何页面进行 linting(除了 pages/_app.js) - Next.js - Eslint is not linting any pages in dev mode (aside from pages/_app.js) 等待_app.js加载,然后在Next.js上运行组件 - Wait _app.js loaded then run component on Next.js 如何在 _app.js 中使用 getStaticProps 在 Next.js 的每个页面中显示从 api 获取的数据 - How to use getStaticProps in _app.js for showing data fetched from api in every pages in Next.js 如何将 next.js 中的 pageProps 从子组件传递给 _app.js? - How to pass pageProps in next.js from a child component to _app.js? Next.js 上下文提供程序包装 App 组件,页面特定的布局组件提供未定义的数据 - Next.js context provider wrapping App component with page specific layout component giving undefined data _app.js class 组件 Next.js 中的上下文 API 调度(消费者) - Context API dispatch (consumer) in _app.js class component Next.js Next.js - 页面未将 GetServerSideProps 放入页面组件道具中(使用自定义 _app.js) - Next.js - Page not getting GetServerSideProps into Page component props (with custom _app.js) 在Next.JS 6中使用_app.js页面组件时,转换触发得太早了 - Transitions are firing too early when using _app.js page component in Next.JS 6 Next.js 和 Typescript - 如何在功能组件中访问 app.js 的 props 和 staticProps - Next.js with Typescript - how to access app.js props and staticProps in functional component 如何在 Next.js 中获取 _app.js 的状态? - How to get state of _app.js in Next.js?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM