v0.13: NextJS App Router, Expo, React 19, Redux
Plataformas:
Pruebas:
- MockResolver marcado como código 'client' para NextJS App Router
- Se exporta renderDataHook() - compatible con React 17 y 18
Paquetes movidos dentro de @data-client/react:
- Redux
- Hooks
Otras mejoras
- Se agregó controller.set(Todo, { id }, { id, completed: false })
- RestEndpoint.path admite +, * y {}
- Se corrigió el valor de retorno de controller.fetch() para Unions
- actionTypes.SET_TYPE -> actionTypes.SET_RESPONSE_TYPE
- SetAction -> SetResponseAction
- Versión mínima de React 16.8.4 -> 16.14
La versión 0.12 se omitió debido a un percance en la publicación.
Plataformas
NextJS App Router
NextJS 12 incluye una nueva forma de enrutamiento en el directorio '/app'. Esto permite más mejoras de rendimiento, así como enrutamiento dinámico y anidado. Esto convierte a NextJS en una plataforma viable para construir aplicaciones dinámicas ricas, en lugar de solo sitios web estáticos.
Mientras que otros métodos de obtención de datos requieren una lenta obtención del lado del cliente, Reactive Data Client ofrece lo mejor de las SPA y de las MPA. #3074, #3093
Como las MPA, el SSR con Data Client significa la carga inicial de página más rápida posible. Como las SPA, Data Client ofrece una navegación, unas mutaciones del lado del cliente y unas mutaciones impulsadas desde el servidor (como websockets) más rápidas que las MPA.
Además, Data Client con SSR sigue ofreciendo las ventajas de rendimiento frente a otras bibliotecas de obtención de datos del lado del cliente.
Data Client realiza SSR en streaming del HTML, agilizando la experiencia de carga inicial de la aplicación. De forma única, Data Client queda entonces interactivo de inmediato con 0 obtenciones de datos del lado del cliente. Esto se logra inicializando el Store del cliente con datos normalizados durante la fase de SSR.
Uso
Renderiza DataProvider desde el punto de entrada /nextjs en tu layout raíz.
import { DataProvider } from '@data-client/react/nextjs';
import { AsyncBoundary } from '@data-client/react';
export default function RootLayout({ children }) {
return (
<html>
<body>
<DataProvider>
<header>Title</header>
<AsyncBoundary>{children}</AsyncBoundary>
<footer></footer>
</DataProvider>
</body>
</html>
);
}
Demo de mutaciones
Explora el ejemplo nextjs
Demo de datos en vivo
Otros SSR
Se agrega el punto de entrada /ssr, eliminando por completo la necesidad del paquete @data-client/ssr d1b9e96
import {
createPersistedStore,
createServerDataComponent,
} from '@data-client/ssr';
import {
createPersistedStore,
createServerDataComponent,
} from '@data-client/react/ssr';
Esto hace posible integrar fácilmente Data Client en cualquier framework de SSR. Agradecemos las contribuciones para la integración con cualquier framework de código abierto.
Expo
Hemos comenzado a trabajar en demos de Expo/ExpoGo y, gracias a ello, encontramos y corregimos algunos problemas de compatibilidad con estas integraciones. Por favor, reporta cualquier problema que se nos haya podido escapar.
React 19
Ahora admitimos React 19. #3071
Esto requirió abandonar el soporte para versiones anteriores a 16.14, ya que debemos usar el runtime de jsx exportado por el propio React. Esto tiene el beneficio adicional de reducir el tamaño del bundle.
Redux
Se agrega @data-client/react/redux #3099. Esto elimina la necesidad del paquete separado @data-client/redux.
import {
ExternalDataProvider,
PromiseifyMiddleware,
applyManager,
initialState,
createReducer,
prepareStore,
} from '@data-client/redux';
import {
ExternalDataProvider,
PromiseifyMiddleware,
applyManager,
initialState,
createReducer,
prepareStore,
} from '@data-client/react/redux';
Se agrega el argumento middlewares a prepareStore() #3099
const { store, selector, controller } = prepareStore(
initialState,
managers,
Controller,
otherReducers,
extraMiddlewares,
);
controller.set()
controller.set() actualiza cualquier Schema Queryable. #3105, #3129
ctrl.set(
Todo,
{ id: '5' },
{ id: '5', title: 'tell me friends how great Data Client is' },
);
Se pueden usar funciones como valor cuando se trabaja con datos derivados. Esto evita condiciones de carrera.
const id = '2';
ctrl.set(Article, { id }, article => ({ id, votes: article.votes + 1 }));
La respuesta debe incluir valores suficientes para calcular Entity.pk()
Esto hace más directo manipular el store con Managers.
Por ejemplo, podemos establecer directamente nuestra entidad Ticker al recibir mensajes de websocket:
Explora el ejemplo coin-app
Mejoras de tipos
-
Se mejora la coincidencia de tipos del controller para sus métodos #3043
-
Se mejora la coincidencia de tipos de los argumentos de useFetch(), de forma similar a useSuspense() #3043
Cambios en REST
Cadenas de path
Se admiten + y * y {} en RestEndpoint.path. a6b4f4a
const getThing = new RestEndpoint({
path: '/:attr1?{-:attr2}?{-:attr3}?',
});
getThing({ attr1: 'hi' });
getThing({ attr2: 'hi' });
getThing({ attr3: 'hi' });
getThing({ attr1: 'hi', attr3: 'ho' });
getThing({ attr2: 'hi', attr3: 'ho' });
ctrl.fetch() y Unions
Los valores de Unions en el valor de retorno de ctrl.fetch() ahora son una instancia de su clase Entity. #3063
import { getFeed } from './Feed'; function useFeedHandler() { const ctrl = useController(); const handleSomething = async () => { const feed = await ctrl.fetch(getFeed); return feed.map(item => { if (item.type == 'link') { // we can use class defined getter return item.anchor; } }); } return handleSomething; }
Guía de migración
Esta actualización requiere actualizar todas las versiones de los paquetes simultáneamente.
- NPM
- Yarn
- pnpm
- esm.sh
npm install --save @data-client/react@^0.13.0 @data-client/rest@^0.13.0 @data-client/test@^0.13.0 @data-client/img@^0.13.0
yarn add @data-client/react@^0.13.0 @data-client/rest@^0.13.0 @data-client/test@^0.13.0 @data-client/img@^0.13.0
pnpm add @data-client/react@^0.13.0 @data-client/rest@^0.13.0 @data-client/test@^0.13.0 @data-client/img@^0.13.0
<script type="importmap">
{
"imports": {
"@data-client/react": "https://esm.sh/@data-client/react@^0.13.0",
"@data-client/rest": "https://esm.sh/@data-client/rest@^0.13.0",
"@data-client/test": "https://esm.sh/@data-client/test@^0.13.0",
"@data-client/img": "https://esm.sh/@data-client/img@^0.13.0"
}
}
</script>
actionTypes.SET_TYPE -> actionTypes.SET_RESPONSE_TYPE
Si escribiste un Manager personalizado que manejaba actionTypes.SET_TYPE, tendrás que
renombrarlo a actionTypes.SET_RESPONSE_TYPE.
import type { Manager, Middleware } from '@data-client/react';
import { actionTypes } from '@data-client/react';
export default class LoggingManager implements Manager {
middleware: Middleware = controller => next => async action => {
switch (action.type) {
case actionTypes.SET_TYPE:
console.info(
`${action.endpoint.name} ${JSON.stringify(action.response)}`,
);
return next(action);
// actions must be explicitly passed to next middleware
default:
return next(action);
}
};
cleanup() {}
}
import type { Manager, Middleware } from '@data-client/react';
import { actionTypes } from '@data-client/react';
export default class LoggingManager implements Manager {
middleware: Middleware = controller => next => async action => {
switch (action.type) {
case actionTypes.SET_RESPONSE_TYPE:
console.info(
`${action.endpoint.name} ${JSON.stringify(action.response)}`,
);
return next(action);
// actions must be explicitly passed to next middleware
default:
return next(action);
}
};
cleanup() {}
}
SetAction -> SetResponseAction
React 16.14+
Cambia la versión mínima de React de 16.8.4 -> 16.14. No se necesitan cambios en el código.
- NPM
- Yarn
- pnpm
- esm.sh
npm install --save react@16.14 react-dom@16.14
yarn add react@16.14 react-dom@16.14
pnpm add react@16.14 react-dom@16.14
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@16.14",
"react-dom": "https://esm.sh/react-dom@16.14"
}
}
</script>
CacheProvider -> DataProvider
Pásate a DataProvider para mantener la compatibilidad con versiones futuras. También se
exporta como CacheProvider, así que no es un cambio incompatible. #3095
import { CacheProvider } from '@data-client/react';
import ReactDOM from 'react-dom';
ReactDOM.createRoot(document.body)
.render(
<CacheProvider>
<App />
</CacheProvider>,
);
import { DataProvider } from '@data-client/react';
import ReactDOM from 'react-dom';
ReactDOM.createRoot(document.body)
.render(
<DataProvider>
<App />
</DataProvider>,
);
Soporte para la actualización
Como siempre, si tienes algún problema o pregunta, no dudes en unirte a nuestro o reportar un error
