https://github.com/ricokahler/hocify
a simple library that converts hooks to HOCs for compatibility with class-based components.
https://github.com/ricokahler/hocify
higher-order-component react react-hooks reactjs
Last synced: about 1 year ago
JSON representation
a simple library that converts hooks to HOCs for compatibility with class-based components.
- Host: GitHub
- URL: https://github.com/ricokahler/hocify
- Owner: ricokahler
- License: mit
- Created: 2019-10-05T02:19:06.000Z (almost 7 years ago)
- Default Branch: main
- Last Pushed: 2025-03-21T23:10:53.000Z (over 1 year ago)
- Last Synced: 2025-03-31T11:02:22.787Z (over 1 year ago)
- Topics: higher-order-component, react, react-hooks, reactjs
- Language: JavaScript
- Homepage:
- Size: 3.89 MB
- Stars: 42
- Watchers: 2
- Forks: 4
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# HOCify · [](https://codecov.io/gh/ricokahler/hocify) [](https://bundlephobia.com/result?p=hocify) [](https://github.com/semantic-release/semantic-release)
> HOCify (H-oh-see-ify) is a simple library that converts hooks to [HOCs](https://reactjs.org/docs/higher-order-components.html) for compatibility with class-based components.
[Hooks](https://reactjs.org/docs/hooks-intro.html) are great! They're the [React team's answer to many problems in React today](https://youtu.be/dpw9EHDh2bM?t=757). However, using them comes with a prerequisite:
> Hooks can only be called inside the body of a function component.
This is unfortunate because it prevents us from using newer hook-based modules in our older class-based components.
This library aims to soften that prerequisite by giving you a reusable tool to convert some hooks into higher-order components.
> **Disclaimer:** The purpose of "using hooks" within class components is more for compatibility of newer hook-based modules with older class-based components. If your component is already implemented as a function, then use the hook directly. If you're writing a new component, try writing it as a function component.
## Installation
```
npm install --save hocify
```
## Usage
`hocify` is a function that takes in a custom hook and returns an HOC.
**⚠️️ There are a few things to note ️️️️️️⚠️**
1. The function you feed into `hocify` is a hook and thus **must follow [the rules of hooks](https://reactjs.org/docs/hooks-rules.html)**
2. The arguments to this hook are the props of the wrapped component. You can write a hook inline to `hocify` that uses these props as an input to other hooks.
3. The resulting inline hook **must** return an object OR `null`. This object will be spread onto the input component as props.
`ExampleComponent.js`
```js
import React from 'react';
import hocify from 'hocify';
import useMyCustomHook from './useMyCustomHook';
// 1) create a custom hook to feed into HOCify.
// note: it's nice to have this top-level for the hooks linter to work correctly
// `props` are the incoming props of the resulting component
const useHocify = (props) => {
const result = useMyCustomHook(props.inputValue);
// 3) the resulting hook _must_ return an object OR `null`.
return { data: result };
};
const withMyCustomHook = hocify(useHocify);
class ExampleComponent extends React.Component {
render() {
const { data } = this.props;
}
}
export default withMyCustomHook(ExampleComponent);
```
`ParentComponent.js`
```js
import React from 'react';
import ExampleComponent from './ExampleComponent';
function ParentComponent() {
// these props are the arguments to the inline hook in the `hocify` call above
// 👇👇👇
return ;
}
export default ParentComponent;
```
## Examples
### Using two or more hooks with `hocify`
The following example shows how you can use two hooks with `hocify`. Note that it's better to create a combined custom hook over creating multiple HOCs.
```js
import React from 'react';
import hocify from 'hocify';
import useHookOne from './useHookOne';
import useHookTwo from './useHookTwo';
const useHocify = () => {
const one = useHookOne();
const two = useHookTwo();
return { one, two };
};
// only create one HOC
const withHooks = hocify(useHocify);
class ClassComponent extends React.Component {
// ...
}
export default withHooks(ClassComponent);
```
### Reacting to prop changes
The following example shows how you can use `props` in `hocify(props =>` to react to prop changes. There is a `useEffect` in our example hook that will re-run if the `id` changes.
`useFetchMovie.js`
```js
function useFetchMovie(id) {
const [movie, setMovie] = useState(null);
useEffect(() => {
async function getData() {
const response = await fetch(`/api/movies/${id}`);
const movie = await response.json();
setMovie(movie);
}
getData();
}, [id]);
return movie;
}
```
`MyComponent.js`
```js
import React, { useState } from 'react';
import useFetchMovie from './useFetchMovie';
const useHocify = (props) => {
const movie = useFetchMovie(props.id);
return { movie };
};
const withFetchMovie = hocify(useHocify);
class MyComponent extends React.Component {
render() {
const { movie } = this.props;
// ...
}
}
export default withFetchMovie(MyComponent);
```