HOCify ·
![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)
HOCify (H-oh-see-ify) is a simple library that converts hooks to HOCs for compatibility with class-based components.
Hooks are great! They're the React team's answer to many problems in React today. 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 ️️️️️️⚠️
- The function you feed into
hocify
is a hook and thus must follow the rules of hooks - 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. - The resulting inline hook must return an object OR
null
. This object will be spread onto the input component as props.
ExampleComponent.js
import React from 'react';
import hocify from 'hocify';
import useMyCustomHook from './useMyCustomHook';
const useHocify = (props) => {
const result = useMyCustomHook(props.inputValue);
return { data: result };
};
const withMyCustomHook = hocify(useHocify);
class ExampleComponent extends React.Component {
render() {
const { data } = this.props;
}
}
export default withMyCustomHook(ExampleComponent);
ParentComponent.js
import React from 'react';
import ExampleComponent from './ExampleComponent';
function ParentComponent() {
return <ExampleComponent inputValue="test" anotherProp={5} />;
}
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.
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 };
};
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
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
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);