Saltar al contenido principal

v0.9: DevTools, Resource.extend y limpieza de APIs heredadas

· 8 min de lectura
Nathaniel Tucker
Creator of Reactive Data Client

Esta versión se centra en la experiencia de desarrollo con un botón de devtools que aparece en modo de desarrollo, un mejor historial de DevTools y nuevos métodos del controller como controller.expireAll() y controller.fetchIfStale().

Resource.extend() ofrece tres formas potentes de personalizar recursos: agregar nuevos endpoints, sobrescribir los existentes o derivar a partir de los endpoints base.

const UserResource = createResource({
path: '/users/:id',
schema: User,
}).extend('current', {
path: '/users/current',
});
Guía de migración

Cambios incompatibles:

Resource.extend() (desde 0.5)​

Resource.extend() ofrece tres formas potentes de personalizar recursos. 51b4b0d

Agregar nuevos endpoints​

const UserResource = createResource({
path: '/users/:id',
schema: User,
}).extend('current', {
path: '/users/current',
});

Sobrescribir endpoints existentes​

const CachedArticleResource = ArticleResource.extend({
getList: {
dataExpiryLength: 10 * 60 * 1000, // 10 minutes
},
});

Derivar a partir de los endpoints base​

const IssueResource = createResource({
path: '/issues/:id',
schema: Issue,
}).extend(Base => ({
byRepo: Base.getList.extend({
path: '/repos/:owner/:repo/issues',
}),
}));

Métodos del Controller​

controller.expireAll() (desde 0.3)​

Marca todas las respuestas coincidentes como obsoletas, lo que dispara una nueva obtención en segundo plano mientras se muestran los datos existentes. #2802

// Mark all article lists as stale - they'll refetch when rendered
controller.expireAll(ArticleResource.getList);

Esto difiere de invalidateAll(), que elimina los datos por completo. expireAll() sigue mostrando los datos en caché mientras obtiene datos frescos en segundo plano.

controller.fetchIfStale() (desde 0.4)​

Obtiene los datos solo si se consideran obsoletos; de lo contrario, devuelve los datos en caché. #2804

// Perfect for prefetching - won't overfetch fresh data
const resolveData = async (controller, { owner, repo }) => {
await controller.fetchIfStale(IssueResource.getList, { owner, repo });
};

Mejoras en DevTools​

Botón de DevTools​

Ahora aparece un botón flotante en modo de desarrollo para abrir rápidamente la extensión Redux DevTools. #2803

Configúralo o desactívalo con la prop devButton:

// Disable the button
<CacheProvider devButton={null}>
<App />
</CacheProvider>
// Position it differently
<CacheProvider devButton="top-right">
<App />
</CacheProvider>

Historial persistente​

DevTools ya no olvida el historial si no estaba abierto al cargar la página. 2d2e941

Mejor seguimiento del estado​

Como React 18 agrupa las actualizaciones, el estado real a veces puede actualizarse a partir de varias acciones. Cuando las devtools están abiertas, un estado sombra refleja con precisión los cambios de cada acción para facilitar la depuración. c9ca31f

Propiedades de Endpoint visibles​

Las propiedades de los Endpoints ahora son completamente visibles en el inspector de devtools. a7da00e

Mejoras en Collection​

Filtrado por argumentos FormData (desde 0.4)​

Las Collections ahora pueden filtrar según argumentos FormData. f95dbc6

ctrl.fetch(getPosts.push, { group: 'react' }, new FormData(e.currentTarget));

Si el FormData contiene un campo author, el elemento recién creado se agregará correctamente a las collections filtradas por ese autor.

paginationField (desde 0.7)​

Usa paginationField para un soporte de paginación sencillo. c8c557

const TodoResource = createResource({
path: '/todos/:id',
schema: Todo,
paginationField: 'page',
});

// Fetches page 2 and appends to the collection
ctrl.fetch(TodoResource.getList.getPage, { page: '2' });

Otras mejoras​

  • Se agrega className a ErrorBoundary y errorClassName a AsyncBoundary #2785
  • Nueva exportación getDefaultManagers() para un control explícito de los managers #2791
  • Se reemplaza BackupBoundary por UniversalSuspense + BackupLoading #2803
  • Entity.process() recibe los args del endpoint como cuarto parámetro (desde 0.7) a8936f5
  • nonFilterArgumentKeys en Collection para excluir los parámetros de ordenamiento del filtrado (desde 0.7) 318df89

Guía de migración​

Esta actualización requiere actualizar todas las versiones de los paquetes al mismo tiempo.

npm install --save @data-client/react@^0.9.0 @data-client/rest@^0.9.0 @data-client/test@^0.9.0 @data-client/img@^0.9.0 @data-client/hooks@^0.9.0

Se eliminan las exportaciones /next​

Se eliminaron todas las exportaciones de la subruta /next. Las funcionalidades que antes estaban en /next ahora son las exportaciones estándar. f65cf83

Before
import { useController } from '@data-client/react/next';
After
import { useController } from '@data-client/react';

makeCacheProvider eliminado​

Usa el componente proveedor directamente con makeRenderDataClient. #2787

Before
import { makeCacheProvider } from '@data-client/react';
const renderDataClient = makeRenderDataClient(makeCacheProvider);
After
import { CacheProvider } from '@data-client/react';
const renderDataClient = makeRenderDataClient(CacheProvider);

Tipo de acción DELETE -> INVALIDATE​

El tipo de acción DELETE pasa a llamarse INVALIDATE para mayor claridad. #2784

Before
import { DELETE_TYPE } from '@data-client/react';
After
import { INVALIDATE_TYPE } from '@data-client/react';

Se abandona el soporte de schemas heredados​

Se eliminó todo el soporte para schemas heredados. Asegúrate de estar usando la clase Entity actual. #2784

  • entity.expiresAt eliminado
  • Se eliminan todas las sobrescrituras de Entity que existían por compatibilidad hacia atrás

Los serializadores de Schema deben admitir llamadas como función​

Los serializadores de Schema ahora deben admitir llamadas como función. Date ya no funciona directamente. #2795

Before
class MyEntity extends Entity {
createdAt = new Date();

static schema = {
createdAt: Date,
};
}
After
class MyEntity extends Entity {
createdAt = new Date();

static schema = {
createdAt: (iso: string) => new Date(iso),
};
}

Como alternativa, usa Temporal:

import { Temporal } from 'temporal-polyfill';

class MyEntity extends Entity {
createdAt = Temporal.Instant.fromEpochSeconds(0);

static schema = {
createdAt: Temporal.Instant.from,
};
}

Tipos de acción con el prefijo 'rdc'​

Todos los tipos de acción ahora llevan el prefijo 'rdc' para un mejor espacio de nombres. #2781

Nombres de acción receive -> set​

Todos los nombres de acción 'receive' pasan a llamarse 'set'. #2782

Before
import { ReceiveAction, RECEIVE_TYPE } from '@data-client/react';
controller.receive(endpoint, args, response);
After
import { SetAction, SET_TYPE } from '@data-client/react';
controller.set(endpoint, args, response);

API de Middleware simplificada​

El Middleware ya no recibe controller como una propiedad desestructurada: recibe el controller directamente. #2786

Before
class LoggingManager implements Manager {
getMiddleware = (): Middleware => ({ controller }) => next => async action => {
console.log('before', action, controller.getState());
await next(action);
console.log('after', action, controller.getState());
};

cleanup() {}
}
After
class LoggingManager implements Manager {
getMiddleware = (): Middleware => controller => next => async action => {
console.log('before', action, controller.getState());
await next(action);
console.log('after', action, controller.getState());
};

cleanup() {}
}

getDefaultManagers()​

Los elementos CacheProvider ya no comparten los managers predeterminados. Usa getDefaultManagers() para un control explícito. #2791

import { getDefaultManagers, CacheProvider } from '@data-client/react';

const managers = getDefaultManagers();

<CacheProvider managers={managers}>
<App />
</CacheProvider>

Soporte para la actualización​

Como siempre, si tienes algún problema o pregunta, no dudes en unirte a nuestro Chat o reportar un error