Pular para o conteúdo principal

v0.13: NextJS App Router, Expo, React 19, Redux

· 9 min para ler
Nathaniel Tucker
Creator of Reactive Data Client

Plataformas:

Testes:

Pacotes movidos para dentro de @data-client/react:

  • Redux
  • Hooks

Outras melhorias

Mudanças incompatíveis:

observação

A versão 0.12 foi pulada devido a um problema na publicação.

Plataformas​

NextJS App Router​

O NextJS 12 inclui uma nova forma de roteamento no diretório '/app'. Isso permite mais melhorias de desempenho, além de roteamento dinâmico e aninhado. Isso torna o NextJS uma plataforma viável para construir aplicações ricas e dinâmicas, e não apenas sites estáticos.

Enquanto outros métodos de busca exigem uma busca lenta no lado do cliente, o Reactive Data Client oferece o melhor de SPA e MPA. #3074, #3093

Como as MPAs, o SSR com Data Client significa o carregamento inicial da página mais rápido possível. Como as SPAs, o Data Client oferece navegação, mutações no lado do cliente e mutações disparadas remotamente (como websockets) mais rápidas do que as MPAs.

Além disso, o Data Client com SSR continua oferecendo as vantagens de desempenho sobre outras bibliotecas de busca no lado do cliente.

Desempenho vs busca no cliente
Bar lengths use a log scale
LCP3xClient fetch 1200 ms → Data Client 400 ms
Mutation603xClient fetch 1810 ms → Data Client 3 ms
List to detail navigation6.7xClient fetch 310 ms → Data Client 46 ms

O Data Client realiza SSR em streaming do HTML, agilizando a experiência de carregamento inicial da aplicação. De forma única, o Data Client fica então imediatamente interativo com 0 buscas no lado do cliente. Isso é alcançado inicializando a store do cliente com dados normalizados durante a fase de SSR.

Uso​

Renderize o DataProvider do ponto de entrada /nextjs no seu layout raiz.

app/layout.tsx
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>
);
}

Demonstração de mutações​

Explore o exemplo nextjs

Mais demos

Demonstração de dados ao vivo​

Outros SSR​

Adiciona o ponto de entrada /ssr - eliminando completamente a necessidade do pacote @data-client/ssr d1b9e96

Before
import {
createPersistedStore,
createServerDataComponent,
} from '@data-client/ssr';
After
import {
createPersistedStore,
createServerDataComponent,
} from '@data-client/react/ssr';

Isso torna possível integrar facilmente o Data Client a qualquer framework de SSR. Recebemos de bom grado contribuições para a integração com qualquer framework open source.

Expo​

Começamos a trabalhar em demonstrações com Expo/ExpoGo e, com isso, encontramos e corrigimos alguns problemas de compatibilidade nessas integrações. Por favor, relate qualquer problema que possa ter passado despercebido.

React 19​

Agora damos suporte ao React 19. #3071

Isso exigiu abandonar o suporte a versões anteriores à 16.14, já que precisamos usar o runtime de jsx exportado pelo próprio React. Isso tem o benefício adicional de reduzir o tamanho do bundle.

Redux​

Adiciona @data-client/react/redux #3099. Isso elimina a necessidade do pacote separado @data-client/redux.

Before
import {
ExternalDataProvider,
PromiseifyMiddleware,
applyManager,
initialState,
createReducer,
prepareStore,
} from '@data-client/redux';
After
import {
ExternalDataProvider,
PromiseifyMiddleware,
applyManager,
initialState,
createReducer,
prepareStore,
} from '@data-client/react/redux';

Adiciona o argumento middlewares a prepareStore() #3099

const { store, selector, controller } = prepareStore(
initialState,
managers,
Controller,
otherReducers,
extraMiddlewares,
);

controller.set()​

controller.set() atualiza qualquer Schema Queryable. #3105, #3129

ctrl.set(
Todo,
{ id: '5' },
{ id: '5', title: 'tell me friends how great Data Client is' },
);

Funções podem ser usadas no valor quando há dados derivados. Isso evita condições de corrida.

const id = '2';
ctrl.set(Article, { id }, article => ({ id, votes: article.votes + 1 }));
observação

A resposta deve incluir valores suficientes para calcular Entity.pk()

Isso torna mais direto manipular a store com Managers. Por exemplo, podemos definir diretamente nossa entidade Ticker ao receber mensagens de websocket:

Explore o exemplo coin-app

Mais demos

Melhorias de tipos​

Mudanças no REST​

Strings de path​

Suporte a + e * e {} em 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() e Unions​

Valores de Unions no valor de retorno de ctrl.fetch() agora são uma instância de sua classe 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;
}

Guia de migração​

Esta atualização exige atualizar todas as versões dos pacotes ao mesmo tempo.

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

actionTypes.SET_TYPE -> actionTypes.SET_RESPONSE_TYPE​

Se você escreveu um Manager personalizado que tratava actionTypes.SET_TYPE, precisará renomeá-lo para actionTypes.SET_RESPONSE_TYPE.

Before
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() {}
}
After
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+​

Altera a versão mínima do React de 16.8.4 -> 16.14. Nenhuma alteração de código é necessária.

npm install --save react@16.14 react-dom@16.14

CacheProvider -> DataProvider​

Migre para o DataProvider para garantir compatibilidade com versões futuras. Ele também é exportado como CacheProvider, então esta não é uma mudança incompatível. #3095

Before
import { CacheProvider } from '@data-client/react';
import ReactDOM from 'react-dom';

ReactDOM.createRoot(document.body)
.render(
<CacheProvider>
<App />
</CacheProvider>,
);
Before
import { DataProvider } from '@data-client/react';
import ReactDOM from 'react-dom';

ReactDOM.createRoot(document.body)
.render(
<DataProvider>
<App />
</DataProvider>,
);

Suporte à atualização​

Como sempre, se você tiver qualquer problema ou dúvida, fique à vontade para entrar no nosso Chat ou registrar um bug