Saltar al contenido principal

Imágenes y otros medios

Después de configurar Reactive Data Client para obtener datos estructurados, quizás quieras incorporar también algunas cargas de medios para aprovechar suspense y el soporte del modo concurrente.

Almacenar un ArrayBuffer​

Resource y Entity no deben usarse en este caso, ya que ambos representan estructuras de mapa string -> valor. En su lugar, definiremos nuestro propio Endpoint simple.

import { Endpoint } from '@data-client/rest';

export const getPhoto = new Endpoint(async ({ userId }: { userId: string }) => {
const response = await fetch(`/users/${userId}/photo`);
const photoArrayBuffer = await response.arrayBuffer();

return photoArrayBuffer;
});
// photo is typed as ArrayBuffer
const photo = useSuspense(getPhoto, { userId });

Solo imágenes​

En muchos casos sería útil suspender la carga de elementos costosos como las imágenes usando suspense. Esto resulta especialmente potente con el patrón fetch as you render en modo concurrente.

@data-client/img ofrece un componente <Img /> que suspende, así como un endpoint getImage para precargar.

Instalación​

npm install --save @data-client/img

Uso​

Profile.tsx
import React, { ImgHTMLAttributes } from 'react';
import { useSuspense } from '@data-client/react';
import { Img } from '@data-client/img';
import { UserResource } from './resources/User';

export default function Profile({ username }: { username: string }) {
const user = useSuspense(UserResource.get, { username });
return (
<div>
<Img
src={user.img}
alt="React Logo"
style={{ height: '32px', width: '32px' }}
/>
<h2>{user.fullName}</h2>
</div>
);
}

Precarga​

Ten en cuenta que esto encadenará las peticiones: hay que esperar a que se resuelva el usuario antes de que pueda comenzar la petición de la imagen. Si la URL de la imagen es determinista a partir de los mismos parámetros, podemos iniciar esa petición al mismo tiempo que la del usuario:

Profile.tsx
import React, { ImgHTMLAttributes } from 'react';
import { useSuspense, useFetch } from '@data-client/react';
import { Img, getImage } from '@data-client/img';
import { UserResource } from './resources/User';

export default function Profile({ username }: { username: string }) {
const imageSrc = `/profile_images/${username}}`;
useFetch(getImage, { src: imageSrc });
const user = useSuspense(UserResource.get, { username });
return (
<div>
<Img
src={imageSrc}
alt="React Logo"
style={{ height: '32px', width: '32px' }}
/>
<h2>{user.fullName}</h2>
</div>
);
}

Al usar el patrón fetch as you render en modo concurrente, usa Controller.fetch() con el Endpoint getImage para precargar la imagen.