Next.js布局组件,传递 prop 给孩子

pxiryf3j  于 2023-03-18  发布在  其他
关注(0)|答案(4)|浏览(238)

我已经找到了一个代码,解决了我的问题,在Next.js重新渲染时,改变页面。但现在我需要发送 prop 到儿童组件。我不知道我怎么能使它在这里工作,这是我的layout.js代码。正如你所看到的,我可以发送 prop 到标题组件,但儿童我不知道如何,因为它是一个变量,而不是一个组件。

import Header from "../components/header";
import Footer from "../components/footer";
import { Fragment } from "react";

export default function Layout({ children, ...pageProps }) {
  return (
    <Fragment>
      <Header
        isRegisterPage={pageProps.isRegisterPage}
        isLoginPage={pageProps.isLoginPage}
        outHome={pageProps.outHome}
      />
      {children}
      <Footer />
    </Fragment>
  );
}

谢谢你的帮助

5n0oy7gb

5n0oy7gb1#

你考虑过使用React的API吗?这个想法是当使用ContextAPI时,你的组件的状态被提升,在全局范围内被管理。如果一个组件需要一个prop,而不是手动传递prop(适当钻取)您可以简单地将组件 Package 在上下文提供程序中,这将允许组件访问应用程序全局状态,这很好,因为,当你的应用程序变得更大时,你可能需要通过许多组件传递 prop ,这会使程序变得混乱,增加不必要的混乱。
React提供了一些很棒的文档来设置您的React应用程序以使用上下文API。强烈推荐查看它!
https://reactjs.org/docs/context.html

wlsrxk51

wlsrxk512#

试试这个

import Header from "../components/header";
import Footer from "../components/footer";
import { Fragment } from "react";

export default function Layout({ children, ...pageProps }) {

  function recursiveMap(children, fn) {
    return React.Children.map(children, child => {
      if (!React.isValidElement(child) || typeof child.type == 'string') {
        return child;
      }
  
      if (child.props.children) {
        child = React.cloneElement(child, {
          children: recursiveMap(child.props.children, fn)
        });
      }
  
      return fn(child);
    });
  }

  // Add props to all child elements.
  const childrenWithProps = recursiveMap(children, child => {
    // Checking isValidElement is the safe way and avoids a TS error too.
    if (isValidElement(child)) {
      // Pass additional props here
      return cloneElement(child, { currentUser: { ...user } })
    }

    return child;
  });

  return (
    <Fragment>
      <Header
        isRegisterPage={pageProps.isRegisterPage}
        isLoginPage={pageProps.isLoginPage}
        outHome={pageProps.outHome}
      />
      {childrenWithProps}
      <Footer />
    </Fragment>
  );
}
bybem2ql

bybem2ql3#

您可以使用React的cloneElement来实现这一点。

React.cloneElement(children, {
    isRegisterPage: pageProps.isRegisterPage,
    isLoginPage: pageProps.isLoginPage,
    outHome: pageProps.outHome
})

您案例中的完整示例:

import Header from "../components/header";
import Footer from "../components/footer";
import React, { Fragment } from "react";

export default function Layout({ children, ...pageProps }) {
  return (
    <Fragment>
      <Header
        isRegisterPage={pageProps.isRegisterPage}
        isLoginPage={pageProps.isLoginPage}
        outHome={pageProps.outHome}
      />
      {
          React.cloneElement(children, {
              isRegisterPage: pageProps.isRegisterPage,
              isLoginPage: pageProps.isLoginPage,
              outHome: pageProps.outHome
          })
      }
      <Footer />
    </Fragment>
  );
}
bf1o4zei

bf1o4zei4#

根据LucasRaza的回答,下面是一个使用API将主题应用于不同组件的示例
1.创建上下文文件

//ThemeContex.js
import { createContext, useState } from "react";

export const ThemeContext = createContext();

export const withThemeContext = Component => {
    const WrappedComp = props => {
  
        const [darkColor,lightColor] = ["#3b3b3b", "#ddd"]
        const [lightBackgoround,darkBackgoround] = ["#ececec","#1d2a35"]       

        const darkTheme = {
            backgroundColor: darkBackgoround,
            color:lightColor,
        }

        const lightTheme = {
            backgroundColor: lightBackgoround,
            color:darkColor,
        }

        const themes = {
            darkTheme, lightTheme
        }
    
        const [theme, setTheme] = useState(lightTheme)

    
        const children ={
            theme,
            themes, 
            setTheme,
        }
    
        return(
            <StylesContext.Provider value={{...children}} >
                <Component {...props} />    
            </StylesContext.Provider>
        )
    }
    
    return WrappedComp;
}

1.在_app. js中,导入withThemeContext更高层组件,导出时将其 Package 在MyApp中。

import { withThemeContext } from '../components'

 function MyApp({ Component, pageProps }) {
       return <Component {...pageProps} />
 }

 export default withThemeContext(MyApp)

1.您可以在组件中的任何位置使用主题

import { useContext } from 'react'
 import {ThemeContext} from '../components'

 export default function Home() {
     const { theme } =useContext(ThemeContext)

     return (
         <div id="home" style={theme}>            
             // Home logic...
         </div>
     )
 }

相关问题