Pular para o conteúdo principal

Imagens e outras mídias

Depois de configurar o Reactive Data Client para buscar dados estruturados, você pode querer incorporar também algumas buscas de mídia para aproveitar o suspense e o suporte ao modo concorrente.

Armazenando ArrayBuffer​

Resource e Entity não devem ser usados neste caso, pois ambos representam estruturas de mapa string -> valor. Em vez disso, definiremos nosso próprio Endpoint simples.

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

Apenas imagens​

Em muitos casos, seria útil suspender o carregamento de itens custosos, como imagens, usando suspense. Isso se torna especialmente poderoso com o padrão fetch as you render no modo concorrente.

O @data-client/img fornece um componente <Img /> que suspende, assim como o endpoint getImage para prefetch.

Instalação​

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

Prefetch​

Observe que isso fará as requisições em cascata, esperando o user ser resolvido antes que a requisição da imagem possa começar. Se a url da imagem for determinística com base nos mesmos parâmetros, podemos iniciar essa requisição ao mesmo tempo que a requisição do user:

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

Ao usar o padrão fetch as you render no modo concorrente, use Controller.fetch() com o getImage Endpoint para pré-carregar a imagem.