简体   繁体   中英

How to render a component outside the component that contains the function that renders the first component?

The situation is a bit complicated:

  • inside a component called "LeftSectionHeader" I have a div, which when clicked must render a component;

  • the component to be rendered is called "ProfileMenu", and is basically a div that must be rendered on top of "LeftSectionHeader" itself and another div;

  • All these components are rendered inside another component called "Main".

The problem is that if I define the function inside "LeftSectionHeader", "ProfileMenu" will be rendered inside, while I need it to not only be rendered outside, but even cover it; that's why you'll see some boolean vars inside "Main", because that is the only way i could render it, but it still doesn't cover the other divs. I'll attach the code of each component and how the final result should look below.

LeftSctionHeader:

 function LeftSectionHeader(){
  return(
    <div class="left-section-header">
        <div class="crop" ><img src="./images/profiles/anonimous.png" /></div>
    </div>
  );
}

The div belonging to the "crop" class is the one that must be clicked to render "ProfileMenu"

ProfileMenu:

   function ProfileMenu(){
  
  return(
    <div class="profile-side-menu">
       //A lot of boring stuff
    </div>
  );
}

There are some functions related to this component, but they are not important, so I didn't put them, just ignore it

Main:

var p=true;
var m=true;

    function Main(){
      return(
        <div class="main">
          <Header />
            <div class="left-section">
            {m ? <div><LeftSectionHeader /><LangMenu /></div>  : <ProfileMenu />}
            </div>
          {p ? <PostPage /> : <NoPostsMessage />} //Ignore this line
          </div>
      );
    }

Before clicking on the orange div

After clicking

This might help as guidline, hopefully!

 function LeftSectionHeader({ onClick }){ return( <div class="left-section-header" onClick={onClick}> <div class="crop" ><img src="./images/profiles/anonimous.png" /></div> </div> ); } function Main(){ const [showProfile, setShowProfile] = useState(false); return( <div class="main"> <Header /> <div class="left-section"> {!showProfile ? ( <div> <LeftSectionHeader onClick={() => setShowProfile(true)} /> <LangMenu /> </div> ) : <ProfileMenu />} </div> {p ? <PostPage /> : <NoPostsMessage />} //Ignore this line </div> ); }

The simplest solution might be to pass a handler into the header component to toggle the menu:

function App () {
  const [showMenu, setShowMenu] = useState();
  return (
    <div>
      <Header onMenuToggle={() => setShowMenu(!showMenu)} />
      { showMenu && <Menu /> }
    </div>
  )
}

function Header ({ onMenuToggle }) {
    <div onClick={onMenuToggle}>...</div>
}

Caveat: This will cause the entire App component to re-render when the menu state changes. You can mitigate this by either

  • A) placing the menu state closer to where it's actually needed, like in the sidebar component instead of at the top, or
  • B) using a context or other orthogonal state store.

Another approach would be to leave the state handling in the LeftSectionHeader component and then use a React portal to render the menu elsewhere in the DOM.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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