简体   繁体   English

React 如何将道具发送到 HOC 内部使用的功能组件?

[英]React How to send a prop to a functional component being used inside of a HOC?

I'm curious if it is possible to achieve this when using functional components?我很好奇在使用功能组件时是否可以实现这一点?

Inside of my App.js, found in the first code snippet below, I want to send a Component (here: PageMain) with some props to the HOC.在我的 App.js 中,在下面的第一个代码片段中,我想向 HOC 发送一个带有一些道具的组件(这里:PageMain)。

When trying to do this by sending a JSX with the resp.当试图通过发送一个带有相应的 JSX 来做到这一点时。 prop, I receive the ff.道具,我收到了ff。 error:错误:

Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: .警告:React.jsx: type is invalid -- 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但是得到:. Did you accidentally export a JSX literal instead of a component?您是否不小心导出了 JSX 文字而不是组件?

Which makes sense according to the description, because I am trying to send this instead of an actual Component:根据描述这是有道理的,因为我试图发送这个而不是实际的组件:

<PageMain childContent={<p>Hey I'm the child component content!</p>

But is there a clean way to achieve this?但是有没有一种干净的方法来实现这一点? My idea is to forward the prop to the ultimate receiver, so PageMain can work with我的想法是将道具转发给最终接收者,以便 PageMain 可以使用

{props.childContent && <>props.childContent</>}

My App.js:我的 App.js:

import { PageMain } from "./MyHOCStuff/PageMain";
import { Header } from "./MyHOCStuff/Header";
import { Footer } from "./MyHOCStuff/Footer";
import { withLayout } from "./MyHOCStuff/withLayout";

const PageWithLayout = withLayout(<PageMain childContent={<p>Hey I'm the child component content!</p>} />, Header, Footer)

function App() {
  return (
    <>
      <PageWithLayout message={"Hello from within a HOC."} />
    </>
  );
}

export default App;

My HOC:我的 HOC:

import React from "react";
export const withLayout = (PageComponent, HeaderComponent, FooterComponent) => {
  return function WithPage({ ...props }) {
    console.log(PageComponent.props);
    return (
      <div>
        <HeaderComponent />
        {props.message && <h1>{props.message}</h1>}
        <PageComponent />
        <FooterComponent />        
      </div>
    );
  };
};

The Component, which should ultimately receive the prop:最终应该接收道具的组件:

export const PageMain = ({...props}) =>{
    return <>
        <h2>Page Content Stuff</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adip bla bla bla...</p>
        {props.childContent && <>props.childContent</>}

    </>;
}

The proper way to render a component from props is to call it like this {componentFromProps} .从 props 渲染组件的正确方法是像这样调用它{componentFromProps} Note that you dont really need that childContent props, when you nest content inside a JSX tag, the parent component will receive that content in a prop called children.请注意,您实际上并不需要该 childContent 道具,当您将内容嵌套在 JSX 标记中时,父组件将在名为 children 的道具中接收该内容。 You can then render it like I did with PageMain.然后,您可以像使用 PageMain 一样渲染它。

import React from "react";

export const withLayout = (PageComponent, HeaderComponent, FooterComponent) => {
    return function WithPage(props) {
        return (
            <div>
                {HeaderComponent}
                {props.message && <h1>{props.message}</h1>}
                {PageComponent}
                {FooterComponent}
            </div>
        );
    };
};
const PageMain = ({children}) => {
    return <>
        <h2>Page Content Stuff</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adip bla bla bla...</p>
        {children}
    </>;
}

const Header = <header>my header</header>
const Footer = <footer>my footer</footer>
const PageWithLayout = withLayout(<PageMain><p>Hey I'm the child component content!</p></PageMain>, Header, Footer)

function App() {
    return (
        <>
            <PageWithLayout message={"Hello from within a HOC."}/>
        </>
    );
}


export default App;

Have you tried passing child content like this?您是否尝试过像这样传递子内容?

() => <p>Hey I'm the child component content!</p>

Also, it strikes me that there is an easier way to build your layout using the router:此外,令我震惊的是,有一种更简单的方法可以使用路由器构建布局:

import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Header from 'Components/Layout/Header/Header'
import Footer from 'Components/Layout/Footer/Footer'
import PageA from 'Components/Page/PageA/PageA'
import PageB from 'Components/Page/PageB/PageB'

function App () {
  return (
    <BrowserRouter>
      <Header/>
      <Routes>
        <Route path="/foo" element={<PageA/>}/>
        <Route path="/bar" element={<PageB/>}/>
      </Routes>
      <Footer/>
    </BrowserRouter>
  )
}

export default App

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM