Skip to content

dwjohnston/react-layout-approaches

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

react-layout-approaches

Here, I'm documenting a few different ways to do high level layouts (navs, side bars, etc) with React.

Approach 1

Each page uses a <StandardLayout> component and specifying which elements they need:

eg:

// Adding nothing
export const FooPage = (props: FooPageProps) => {
  const { } = props;
  return <StandardLayout>
    foo page

    <SizedContent/>
  </StandardLayout>;
};
//Specifying side nav and sub nav content 
export const BarPage = (props: BarPageProps) => {
  const { } = props;
  return <StandardLayout

    sideNavContent={
      <SizedContent width={100} height={3000} color="#7f8">I am the side nav. Note that I scroll independently!</SizedContent>
    }
    subNavContent={
      <SizedContent width={800} height={100} color="#6af"> I am some sub nav content. Note that I am sticky!</SizedContent>
    }
  >
    bar page



    <SizedContent />
  </StandardLayout>;
};

Pretty happy with this.

Some learnings:

  • Getting pretty happy with using grid, rather than flex. Named columns/rows is helpful.
  • The min-width:0 / min-height:0 trick, to stop a flex/grid item from growing, is essential. See: https://stackoverflow.com/a/66689926/1068446

Not sure about:

The position of the footer, when the side nav is open. Question for a designer though.

Performance:

I've left a console log in HeaderContent.tsx .

What you can see is that when we click between the Foo and Bar page, the Header Content re-renders. (It doesn't remount though).

Where this could potentially become problematic, is if you have a 'User Menu' type button in your header (where the user access the profile settings, sign out, etc).

I dunno, it's not remounting (which would be the real problem, imagine that the User Menu button did a profile fetch on mount), so I might squibbling here.

Approach 1b

Similar but things that every page must have (like the header, footer) are not included in the StandardLayout component.

I can't be bothered doing this right now.

Approach 2

Use portals instead.

Eg:

// Plain component
export const FooPage = (props: FooPageProps) => {
  const { } = props;
  return <div>
    foo page

    <SizedContent/>
  </div>;
};
//Component with subnav and side nav
export const BarPage = (props: BarPageProps) => {
  const { } = props;
  return <div
  >

    <SubNav>
      <SizedContent width={800} height={100} color="#6af"> I am some sub nav content. Note that I am sticky!</SizedContent>
    </SubNav>

    <SideNav>
      <SizedContent width={100} height={3000} color="#7f8">I am the side nav. Note that I scroll independently!</SizedContent>
    </SideNav>


    <SizedContent />
  </div>;

In this solution, I'm using the same CSS technique to arrange the content as approach 1.

Appraoch 2 has the debatable advantage of not having to put the same boiler plate at the top of each page.

But importantly, it has the advantage of being able to have multiple items put content into the your SubNav/SideSav containers. In the example I've created SomeSubComponent also puts something inside of the subnav. This would be a lot trickier/messier with Approach 1.

Peformance:

Has the same rerendering has Appraoch 1. I think this is because it's the route change that causes the rerender.

About

Here, I'm documenting a few different ways to do high level layouts (navs, side bars, etc) with React.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published