Saltar al contenido principal

Usar hooks con componentes de clase

Los hooks son geniales, pero muchos trabajamos con código existente o bibliotecas basadas en componentes de clase. Algunos podrían migrarse con facilidad, pero otros podrían ser más difíciles. ¿Debería esto impedirte adoptar Reactive Data Client? ¡Por supuesto que no!

Con la sencilla biblioteca de interoperabilidad hook-hoc podemos crear Higher Order Components a partir de hooks con mucha facilidad. Esto nos permite reemplazar cualquier HOC existente sin esfuerzo.

Instalar hook-hoc​

npm install --save hook-hoc

Usar con una clase​

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);

Como puedes ver, el valor de retorno de la función que pasas se inyecta en las props del componente que envuelves.

Extraer la función​

Quizás notes que la función que pasamos a withHook() es una función que llama a hooks. Eso la convierte en un hook por definición. Para que las reglas de los hooks puedan detectarla y, además, para poder reutilizarla, la movemos a una función con nombre:

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 y más​

A menudo harás algo más que simplemente obtener los datos. Podemos hacer todo ese trabajo adicional en el hook que acabamos de crear. Aquí agregaremos filtrado del lado del cliente y también aplicaremos debounce a las propias solicitudes.

Puedes combinar cualquier hook aquí: el cielo es el límite.

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...