@bogoslavskiy/react-slots
TypeScript icon, indicating that this package has built-in type declarations

0.3.4 • Public • Published

Group 1

Allows you to create a hierarchical component model instead of passing large components through render props.

Works with React and React Native.

Install

npm version

$ yarn add @bogoslavskiy/react-slots

Examples

Without slots (Standard practice)

import * as React from 'react';

interface HeaderProps {
  title: string;
}

const Header = React.memo<HeaderProps>(({ title }) => {
  return (
    <div>
      {title}
    </div>
  );
});

const Footer = React.memo(({ children }) => (
  <div>
    {children}
  </div>
));

interface PageProps {
  HeaderComponent: () => React.ReactNode;
  FooterComponent: () => React.ReactNode;
}

const Page = React.memo<PageProps>((props) => {
  const { children, HeaderComponent, FooterComponent } = props;

  return (
    <div>
      <div>
        <div>Render Header</div>
        <div>{HeaderComponent}</div>
      </div>

      <div>{children}</div>

      <div>
        <div>Render Footer</div>
        <div>{FooterComponent}</div>
      </div>
    </div>
  )
});

const App: React.FC = () => {
  const [count, setCount] = React.useState(0);

  return (
    <Page
      HeaderComponent={() => (
        <Header title="Title" />
      )}
      FooterComponent={() => (
        <Footer>
          <div>Count: {count}</div>
          {/* 
            There can be many nested components here.
            The more components, the harder it is to read the code
          */}
        </Footer>
      )}
    >
      <button onClick={() => setCount(count + 1)}>
        Press me
      </button>
    </Page>
  )
};

With slots

import * as React from 'react';
import { createSlot, useSlots } from '@bogoslavskiy/react-slots';

interface HeaderProps {
  title: string;
}

// For convenience, we can separate slot creation from component.
const HeaderSlot = createSlot('Header');
const Header = HeaderSlot.memo<HeaderProps>(({ title }) => {
  return (
    <div>
      {title}
    </div>
  );
});

const Footer = createSlot('Footer').memo(({ children }) => (
  <div>
    {children}
  </div>
));

const Page = React.memo(({ children }) => {
  const Slots = useSlots(children, [
    HeaderSlot.displayName,
    Footer.displayName
  ]);

  return (
    <div>
      <div>
        <div>Render Header</div>
        <div>{Slots.Header}</div>
      </div>

      <div>{children}</div>

      <div>
        <div>Render Footer</div>
        <div>{Slots.Footer}</div>
      </div>
    </div>
  )
});

const App: React.FC = () => {
  const [count, setCount] = React.useState(0);

  return (
    <Page>
      <Header title="Title" />

      <button onClick={() => setCount(count + 1)}>
        Press me
      </button>

       <Footer>
        <div>Count: {count}</div>
      </Footer>
    </Page>
  )
};

Package Sidebar

Install

npm i @bogoslavskiy/react-slots

Weekly Downloads

1

Version

0.3.4

License

MIT

Unpacked Size

10.5 kB

Total Files

7

Last publish

Collaborators

  • bogoslavskiy