Usando hooks com componentes de classe
Hooks são ótimos, mas muitos de nós trabalhamos com bases de código ou bibliotecas existentes baseadas em componentes de classe. Alguns podem ser fáceis de migrar, mas outros podem ser mais difíceis. Isso deveria impedir você de adotar o Reactive Data Client? Claro que não!
Usando a biblioteca simples de interoperabilidade hook-hoc, podemos criar Higher Order Components a partir de hooks com bastante facilidade. Isso nos permite substituir qualquer HOC existente sem esforço.
Instale o hook-hoc
- NPM
- Yarn
- pnpm
- esm.sh
yarn add hook-hoc
npm install --save hook-hoc
pnpm add hook-hoc
<script type="module">
import * from 'https://esm.sh/hook-hoc';
</script>
Uso com classes
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);
Aqui você pode ver que o valor de retorno da função que você passa é injetado nas props do componente que você envolve.
Extraindo a função
Você pode notar que a função que passamos para withHook() é uma função que chama
hooks. Isso a torna um hook por definição. Para que isso seja detectável pelas regras dos hooks
e também potencialmente reutilizável, vamos movê-la para uma função nomeada:
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);
Filtros, debounce e mais
Muitas vezes você fará um pouco mais do que apenas obter os dados. Podemos fazer todo esse trabalho extra no hook que acabamos de criar. Aqui vamos adicionar um pouco de filtragem no cliente, além de aplicar debounce às próprias requisições.
Você pode combinar quaisquer hooks aqui - o céu é o limite.
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...