Framework
Version

Übersicht

Solid Query ist der offizielle SolidJS-Adapter von TanStack Query, der das Abrufen, Cachen, Synchronisieren und Aktualisieren von Serverzuständen in Ihren Webanwendungen zum Kinderspiel macht.

Motivation

SolidJS gewinnt als schnelle, reaktive und deklarative Bibliothek für den Aufbau von Benutzeroberflächen an Popularität. Es ist mit vielen Funktionen im Lieferumfang enthalten. Primitives wie createSignal und createStore eignen sich hervorragend für die Verwaltung von Client-Zuständen. Und im Gegensatz zu anderen UI-Bibliotheken hat SolidJS starke Meinungen zur Verwaltung asynchroner Daten. Die createResource API ist ein großartiges Primitive zur Behandlung von Serverzuständen in SolidJS-Anwendungen. Eine resource ist eine spezielle Art von Signal, das verwendet werden kann, um Suspense-Grenzen auszulösen, wenn sich die Daten im Ladezustand befinden.

tsx
import { createResource, ErrorBoundary, Suspense } from 'solid-js'
import { render } from 'solid-js/web'

function App() {
  const [repository] = createResource(async () => {
    const result = await fetch('https://api.github.com/repos/TanStack/query')
    if (!result.ok) throw new Error('Failed to fetch data')
    return result.json()
  })

  return (
    <div>
      <div>Static Content</div>
      {/* An error while fetching will be caught by the ErrorBoundary */}
      <ErrorBoundary fallback={<div>Something went wrong!</div>}>
        {/* Suspense will trigger a loading state while the data is being fetched */}
        <Suspense fallback={<div>Loading...</div>}>
          <div>{repository()?.updated_at}</div>
        </Suspense>
      </ErrorBoundary>
    </div>
  )
}

const root = document.getElementById('root')

render(() => <App />, root!)
import { createResource, ErrorBoundary, Suspense } from 'solid-js'
import { render } from 'solid-js/web'

function App() {
  const [repository] = createResource(async () => {
    const result = await fetch('https://api.github.com/repos/TanStack/query')
    if (!result.ok) throw new Error('Failed to fetch data')
    return result.json()
  })

  return (
    <div>
      <div>Static Content</div>
      {/* An error while fetching will be caught by the ErrorBoundary */}
      <ErrorBoundary fallback={<div>Something went wrong!</div>}>
        {/* Suspense will trigger a loading state while the data is being fetched */}
        <Suspense fallback={<div>Loading...</div>}>
          <div>{repository()?.updated_at}</div>
        </Suspense>
      </ErrorBoundary>
    </div>
  )
}

const root = document.getElementById('root')

render(() => <App />, root!)

Das ist erstaunlich! Mit wenigen Codezeilen können Sie Daten von einer API abrufen und Lade- und Fehlerzustände behandeln. Aber je komplexer Ihre Anwendung wird, desto mehr Funktionen benötigen Sie, um den Serverzustand effektiv zu verwalten. Das liegt daran, dass Serverzustand völlig anders ist als Client-Zustand. Zunächst einmal ist Serverzustand

  • Remote an einem Ort gespeichert, den Sie nicht kontrollieren oder besitzen
  • Erfordert asynchrone APIs zum Abrufen und Aktualisieren
  • Impliziert geteilte Eigentümerschaft und kann von anderen Personen ohne Ihr Wissen geändert werden
  • Kann in Ihren Anwendungen potenziell "veraltet" sein, wenn Sie nicht vorsichtig sind

Sobald Sie die Natur von Server-Zuständen in Ihrer Anwendung verstanden haben, entstehen weitere Herausforderungen, wie zum Beispiel:

  • Caching... (möglicherweise das Schwierigste in der Programmierung)
  • Deduzierung mehrerer Anfragen für dieselben Daten zu einer einzigen Anfrage
  • Aktualisieren von "veralteten" Daten im Hintergrund
  • Wissen, wann Daten "veraltet" sind
  • Reflektieren von Datenaktualisierungen so schnell wie möglich
  • Leistungsoptimierungen wie Paginierung und verzögertes Laden von Daten
  • Verwaltung von Speicher und Garbage Collection von Server-Zuständen
  • Memoizing von Query-Ergebnissen mit struktureller Teilung

Hier kommt Solid Query ins Spiel. Die Bibliothek umschließt createResource und bietet eine Reihe von Hooks und Dienstprogrammen zur effektiven Verwaltung von Serverzuständen. Sie funktioniert erstaunlich gut out-of-the-box, ohne Konfiguration, und kann nach Belieben angepasst werden, wenn Ihre Anwendung wächst.

Technisch gesehen wird Solid Query wahrscheinlich

  • Ihnen helfen, viele Zeilen komplizierten und missverstandenen Codes aus Ihrer Anwendung zu entfernen und durch nur eine Handvoll Zeilen Solid Query-Logik zu ersetzen.
  • Ihre Anwendung wartungsfreundlicher machen und das Erstellen neuer Funktionen erleichtern, ohne sich Gedanken über die Verkabelung neuer Server-Zustandsdatenquellen machen zu müssen.
  • Einen direkten Einfluss auf Ihre Endbenutzer haben, indem Sie Ihre Anwendung schneller und reaktionsfähiger als je zuvor machen.
  • Potenziell helfen, Bandbreite zu sparen und die Speicherleistung zu verbessern.

Genug geredet, zeig mir endlich Code!

Im folgenden Beispiel sehen Sie Solid Query in seiner grundlegendsten und einfachsten Form, um die GitHub-Statistiken für das TanStack Query GitHub-Projekt selbst abzurufen.

tsx
import { ErrorBoundary, Suspense } from 'solid-js'
import {
  useQuery,
  QueryClient,
  QueryClientProvider,
} from '@tanstack/solid-query'

function App() {
  const repositoryQuery = useQuery(() => ({
    queryKey: ['TanStack Query'],
    queryFn: async () => {
      const result = await fetch('https://api.github.com/repos/TanStack/query')
      if (!result.ok) throw new Error('Failed to fetch data')
      return result.json()
    },
    staleTime: 1000 * 60 * 5, // 5 minutes
    throwOnError: true, // Throw an error if the query fails
  }))

  return (
    <div>
      <div>Static Content</div>
      {/* An error while fetching will be caught by the ErrorBoundary */}
      <ErrorBoundary fallback={<div>Something went wrong!</div>}>
        {/* Suspense will trigger a loading state while the data is being fetched */}
        <Suspense fallback={<div>Loading...</div>}>
          {/* 
            The `data` property on a query is a SolidJS resource  
            so it will work with Suspense and transitions out of the box! 
          */}
          <div>{repositoryQuery.data?.updated_at}</div>
        </Suspense>
      </ErrorBoundary>
    </div>
  )
}

const root = document.getElementById('root')
const client = new QueryClient()

render(
  () => (
    <QueryClientProvider client={client}>
      <App />
    </QueryClientProvider>
  ),
  root!,
)
import { ErrorBoundary, Suspense } from 'solid-js'
import {
  useQuery,
  QueryClient,
  QueryClientProvider,
} from '@tanstack/solid-query'

function App() {
  const repositoryQuery = useQuery(() => ({
    queryKey: ['TanStack Query'],
    queryFn: async () => {
      const result = await fetch('https://api.github.com/repos/TanStack/query')
      if (!result.ok) throw new Error('Failed to fetch data')
      return result.json()
    },
    staleTime: 1000 * 60 * 5, // 5 minutes
    throwOnError: true, // Throw an error if the query fails
  }))

  return (
    <div>
      <div>Static Content</div>
      {/* An error while fetching will be caught by the ErrorBoundary */}
      <ErrorBoundary fallback={<div>Something went wrong!</div>}>
        {/* Suspense will trigger a loading state while the data is being fetched */}
        <Suspense fallback={<div>Loading...</div>}>
          {/* 
            The `data` property on a query is a SolidJS resource  
            so it will work with Suspense and transitions out of the box! 
          */}
          <div>{repositoryQuery.data?.updated_at}</div>
        </Suspense>
      </ErrorBoundary>
    </div>
  )
}

const root = document.getElementById('root')
const client = new QueryClient()

render(
  () => (
    <QueryClientProvider client={client}>
      <App />
    </QueryClientProvider>
  ),
  root!,
)

Nun, das scheinen mehr Codezeilen zu sein, um dasselbe zu tun?

Ja, das stimmt! Aber diese wenigen Codezeilen erschließen eine ganz neue Welt von Möglichkeiten. Im obigen Beispiel wird Ihre Abfrage 5 Minuten lang zwischengespeichert. Das bedeutet, dass, wenn eine neue Komponente irgendwo in Ihrer App eingebunden wird, die dieselbe Abfrage innerhalb von 5 Minuten verwendet, die Daten nicht erneut abgerufen, sondern die zwischengespeicherten Daten verwendet werden. Dies ist nur eine der vielen Funktionen, die Solid Query im Lieferumfang bietet. Einige weitere Funktionen sind:

  • Automatisches erneutes Abrufen: Abfragen werden automatisch im Hintergrund erneut abgerufen, wenn sie "stale" (veraltet gemäß der staleTime-Option) werden.
  • Automatisches Caching: Abfragen werden standardmäßig gecached und in Ihrer Anwendung gemeinsam genutzt.
  • Anforderungsdeduplizierung: Mehrere Komponenten können dieselbe Abfrage gemeinsam nutzen und eine Anfrage stellen.
  • Automatische Speicherbereinigung: Abfragen werden automatisch bereinigt, wenn sie nicht mehr benötigt werden.
  • Fensterfokus-erneutes Abrufen: Abfragen werden automatisch erneut abgerufen, wenn die Anwendung wieder in den Fokus kommt.
  • Paginierung: Eingebaute Unterstützung für Paginierung.
  • Anforderungsabbruch: Bricht veraltete oder unerwünschte Anfragen automatisch ab.
  • Polling/Echtzeit: Es ist einfach, Polling oder Echtzeitaktualisierungen zu Ihren Abfragen mit einer einfachen refetchInterval-Option hinzuzufügen.
  • SSR-Unterstützung: Solid Query funktioniert hervorragend mit serverseitigem Rendering.
  • Optimistische Updates: Aktualisieren Sie Ihren Cache ganz einfach mit optimistischen Updates.
  • Und vieles mehr...