# Using hooks with class components

Hooks are great, but many of us are working with existing codebases or libraries
with class based components. Some might be easy to migrate but others might be
more diffcult. Should this block you from adopting Reactive Data Client? Of course not!

Using the simple [hook-hoc](https://github.com/ntucker/hook-hoc) interop library
we can create Higher Order Components from hooks quite easily. This enables us
to easily replace any existing HOC with ease.

## Install [hook-hoc](https://github.com/ntucker/hook-hoc)

```bash
npm install hook-hoc
```

## Use with class

```tsx
import { PureComponent } from 'react';
import withHook from 'hook-hoc';
import { useSuspense } from '@data-client/react';

import { User, UserResource } from './resources/User';

class Profile extends PureComponent<{
  id: number;
  user: User;
  friends: User[];
}> {
  //...
}

export default withHook(({ id }: { id: number }) => {
  const user = useSuspense(UserResource.get, { id });
  const friends = useSuspense(UserResource.getList, { friendid: id });
  return { user, friends };
})(Profile);
```

Here you can see the return value of the function you pass in gets injected into the props
of the component you wrap.

## Extracting the function

You might notice the function we pass to `withHook()` is a function that calls
hooks. That makes it a hook by definition. To make this detectable by the [rules of hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)
and also potentially reusable, let's move it out to a named function:

```tsx
import { PureComponent } from 'react';
import withHook from 'hook-hoc';
import { useSuspense } from '@data-client/react';

import { User, UserResource } from './resources/User';

function useProfile({ id }: { id: number }) {
  const user = useSuspense(UserResource.get, { id });
  const friends = useSuspense(UserResource.getList, { friendid: id });
  return { user, friends };
}

class Profile extends PureComponent<{
  id: number;
  user: User;
  friends: User[];
}> {
  //...
}

export default withHook(useProfile)(Profile);
```

## Filters, debounce and more

Often times you'll be doing a bit more than just retrieving the data. We can
do all of that extra work in the hook we just created. Here we'll add some
client-side filtering as well as [debouncing](https://usehooks.com/useDebounce/) the requests themselves.

You can combine any hooks here - the sky's the limit.

```tsx
import { useSuspense, useDebounce } from '@data-client/react';

import { UserResource } from './resources/User';

function useProfile({ id }: { id: number }) {
  const debouncedId = useDebounce(id, 150);

  const user = useSuspense(UserResource.get, { id });
  const friends = useSuspense(UserResource.getList, { friendid: id });
  const realFriends = friends.filter(friend => friend.isReal);

  return { user, friends: realFriends };
}

// rest of file...
```
