Search code examples
javascriptreactjschildren

React: Specify Location of Nested Children Components?


How I want to setup my component hierarchy to be setup like this:

<Page>
  <Page.Section>
     <Page.Item/>
  </Page.Section>
</Page>
  1. How do I reference the nested children of children components (aka Page.Item) to put in a different location because I don't want specific styling to effect it? See Code Comments. Due to the styling, I do not want to change it.

  2. How do you only allow Page.Section and Page.Item to be used in Page Component and not standalone?

Page.js

const Page = ({ children }) => {
  return (
    <>
      <div
        className='bg-gray-100 border-b-2 flex flex-col top-0 fixed w-screen transition-height duration-300 mt-16'
      >
        <SomeComponent/>
        // Section Children I want here so it takes styling
        {children}
      </div>
        // Item Children I want here so it does not take styling, but I want the Item Children to always be nested in The Page.Section Component.
        {children.children?}
    </>
  );
};

// I want his Section element to be
const Section = ({ children }) => {
  return (
    <>
      <ConfiguratorTab/>
      {children}
    </>
  );
};

const Item = () => {
  return (
    <>
      <Form/>
    </>
  );
};

Page.Section = Section;
Page.Item = Item;

export default Page;

Solution

  • children returns an object with the following keys and values.

    type: ƒ Section() {}
    key: null
    ref: null
    props: Object
    _owner: FiberNode
    _store: Object
    

    The props object holds the prop values passed to the current(parent) component. So the children of children component could be accessed using props. And since Item is a child of Page (although not a direct child), you need not include it again in the Section component, if you don't want certain styles to be applied to it. This could be accomplished by removing children from Section.

    const Section = ({ children }) => {
      return (
        <>
          <ConfiguratorTab/>
          {//Don't render any children elements here.
          }
        </>
      );
    };
    
    const Page = ({ children }) => {
      return (
        <>
          <div
            className='bg-gray-100 border-b-2 flex flex-col top-0 fixed w-screen transition-height duration-300 mt-16'
          >
            <SomeComponent/>
            // Section Children I want here so it takes styling
            {children}
          </div>
            // Item Children I want here so it does not take styling, but I want the Item Children to always be nested in The Page.Section Component.
            {children.props.children}
        </>
      );
    };