JSPM

  • Created
  • Published
  • Downloads 47
  • Score
    100M100P100Q54746F
  • License MIT

Work with React and HOCs (Higher-Order Components)

Package Exports

  • react-with-hoc
  • react-with-hoc/lib/commonjs/index.js
  • react-with-hoc/lib/module/index.js
  • react-with-hoc/src/index.tsx

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-with-hoc) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

react-with-hoc

Type safe and Zero-cost React library to work with higher-order component (HOC)

Documentation NPM version Build Typescript Bundle size Bundle dependency License

Getting Started

Read the docs

Install with npm

npm install react-with-hoc

Or install with yarn

yarn add react-with-hoc

Usage example

Hello World

import { withDefault, withOverride, withHocs } from "react-with-hoc";

export const Hello = (() => {
  function Hello({ name }: { name: string }) {
    return <div>Hello {name}!</div>;
  }

  return withHocs([withDefault({ name: "World" })])(Hello);
})();

// <Hello /> is equivalent to <div>Hello World!</div>
// <Hello name="You" /> is equivalent to <div>Hello You!</div>

export const HelloYou = withOverride("name", "You")(Hello);

// <HelloYou /> is equivalent to <div>Hello You!</div>
// <HelloYou name="..." /> is a typescript error ❌

Example with react-query

Lets suppose you have the following code and then you need a query inside your App component

const queryClient = new QueryClient();

function App() {
  // Oops... ❌
  // This is an error because App is not wrapped by QueryClientProvider
  const query = useQuery({...});

  return (
    <QueryClientProvider client={queryClient}>
      <>...</>
    </QueryClientProvider>
  );
}

export default App;

Using react-with-hoc, you can easily fix this with:

import {withWrapper, withOverride} from "react-with-hoc";

const queryClient = new QueryClient();

function App() {
  // ✅
  const query = useQuery({...});

  return (
    <>...</>
  );
}

export default withWrapper(
  withOverride({ client: queryClient })(QueryClientProvider)
)(App);

// for didactic purpose, the following code could also be applied
// const MyQueryClientProvider = withOverride({ client: queryClient })(QueryClientProvider)
// export default withWrapper(MyQueryClientProvider)(App);

Using IIFE

import { withWrapper, withOverride, withHocs } from "react-with-hoc";

const queryClient = new QueryClient();

const App = (() => {
  function App() {
    // ✅
    const query = useQuery({...});

    return <>...</>;
  }

  return withHocs([
    withWrapper(withOverride({ client: queryClient })(QueryClientProvider)),
  ])(App);
})();

export default App;

Clock

Check out an entire project with react-with-hoc, see the demo and try to imagine creating a reusable component with the same flexibility

Take a look on how simple it's the final result

const RedHour = withOverride("color", "red")(HourPointer);

const Square = withStyle({
  borderRadius: 0,
})(ClockCircle);

function App(): JSX.Element {
  return (
    <>
      <div>
        <h1>The default clock</h1>
        <Clock />
      </div>
      <div>
        <h1>#1 Variant: without minute marks</h1>
        <Clock MinuteMarks={null} />
      </div>
      <div>
        <h1>#2 With a red hour pointer</h1>
        <Clock HourPointer={(): typeof RedHour => RedHour} />
      </div>
      <div>
        <h1>#3 Inside a square</h1>
        <Clock Circle={(): typeof Square => Square} />
      </div>
    </>
  );
}