highlander-react-hoc

There can be only one (component in DOM)!

Usage no npm install needed!

<script type="module">
  import highlanderReactHoc from 'https://cdn.skypack.dev/highlander-react-hoc';
</script>

README

Highlander React HOC

There can be only one (component in DOM)!


Higher order component that allows only one component of the same type to be rendered.

Note this doesn't work with React.StrictMode. Highlander HOC needs application wide tracking of wrapped components and therefore it's not a pure component.

Use cases

  1. Fire some side effects, and prevent repetition if you have multiple instances of the same component. Example:
const Context = React.createContext();

const FetchSomeDataComponent = highlander(() => {
  const { setData } = React.useContext(Context);

  React.useEffect(() => {
    // this will be executed only once
    // highlander HOC will only allow the first component to be mounted
    setTimeout(() => {
      console.log('fetching!');
      setData('fetched value');
    }, 1000);
  }, []);

  return null;
});

const SomeComponent = () => {
  const { value } = React.useContext(Context);
  return (
    <div>
      <FetchSomeDataComponent />
      <div>this is our {value}</div>
    </div>
  );
};

const FetchExample = () => {
  const [value, setData] = React.useState('');
  return (
    <Context.Provider value={{ value, setData }}>
      <SomeComponent />
      <SomeComponent />
      <SomeComponent />
    </Context.Provider>
  );
};
  1. Render a single component even though you have multiple components in your tree. Example:
const Context = React.createContext();

const Modal = highlander(() => (
  <div>this is our modal</div>
));

const SomeComponent = () => {
  const { modalOpen, setModalOpen } = React.useContext(Context);
  return (
    <div>
      {modalOpen && <Modal />}
      <button onClick={() => setModalOpen(true)}>Open modal</button>
    </div>
  );
};

const ModalExample = () => {
  const [modalOpen, setModalOpen] = React.useState();
  return (
    <Context.Provider value={{ modalOpen, setModalOpen }}>
      <SomeComponent />
      <SomeComponent />
      <SomeComponent />
    </Context.Provider>
  );
};

Full example implementation available in examples folder