Come creare un'app React con RTK-QUERY
È impossibile essere uno sviluppatore front-end che lavora con React e non ha sentito parlare di redux nella tua vita. La maggior parte delle aziende utilizza redux nella propria base di codice e conoscerne i concetti di base è diventata una delle essenze dell'essere un Frontender. Ci sono molte discussioni sull'utilizzo o meno nel tuo prodotto. La verità è che non puoi mai trovare uno strumento perfetto per tutti i progetti. Dovresti decidere quali strumenti sono più adatti ai tuoi obiettivi e al tuo prodotto. Sebbene ci siano alcuni pro e contro per ogni strumento, la cosa più importante è il compromesso tra i vantaggi e gli svantaggi dello strumento per TE .
RTK Query è un potente strumento di recupero e memorizzazione nella cache dei dati. È progettato per semplificare i casi comuni per il caricamento dei dati in un'applicazione Web, eliminando la necessità di scrivere manualmente la logica di recupero e memorizzazione nella cache dei dati.
Se stai usando redux, in particolare redux-toolkit , sai già che rtk-query viene fornito come dipendenza incorporata con esso. Ci sono molti strumenti simili come react-query là fuori, ma quando usi redux-toolkit e hai già rtk-query nel tuo pacchetto, perché non usarlo? Alcuni vantaggi di trk-query sono:
- È completamente compatibile con redux
- Scritto in dattiloscritto
- Migliora il tuo livello di servizio per renderlo più riutilizzabile e porta il tuo progetto con hook generati automaticamente al livello successivo
- È tracciabile e osservabile tramite redux-devtools
- Ha un comportamento di memorizzazione nella cache davvero piacevole
Prerequisito
- Dovresti conoscere React
- Dovresti conoscere i concetti di redux e redux-toolkit e volerli utilizzare nel tuo progetto
- Avere esperienza con TypeScript è un vantaggio, ma puoi semplicemente rimuovere parti TS dai codici e funziona con JavaScript per te :)
Come funziona?
Come accennato in precedenza, rtk-query è uno strumento di recupero che fornisce tantissime funzionalità per rendere il tuo progetto più pulito e riutilizzabile. I tuoi servizi possono essere creati sotto forma di endpoint e query utilizzando createApi che è completamente simile a createReducer . Genera hook per le tue query e puoi usarli facilmente nei tuoi componenti. Non avrai più bisogno di caricare stati, gestione degli errori, funzioni di recupero, prelettura con useEffect e parser di dati perché rtk-query se ne occuperà per te.
In effetti, le query sono le parti più piccole dei tuoi servizi che possono essere GET o POST per ottenere o inviare dati al server. Tutte le query relative a un'entità sono impacchettate in un endpoint creato da createApi . Alla fine, il tuo livello di servizio è una combinazione di diversi endpoint che includono le proprie query.
rtk-query utilizza l'API di recupero da JavaScript. Ma puoi configurarlo per usare axios o graphql. Inoltre, avvolge le tue query per immer in modo che i dati mutanti non siano più un problema.
Costruire le fondamenta
Puoi scegliere QUALSIASI strumento e configurazione che ti piace per questo progetto. Userò Vite, ma non importa se ti piace di più CRA o preferisci configurare il tuo boilerplate. Dopo aver creato il nostro progetto React, dovremmo installare redux-toolkit + axios e configurarlo:
npm install @reduxjs/toolkit react-redux axios
// src/services/api.ts
const axiosBaseQuery =
(): BaseQueryFn<AxiosRequestConfig, unknown, AxiosError> =>
async ({ url, method, data, params }) => {
try {
Axios.defaults.baseURL = "https://jsonplaceholder.typicode.com/";
const result = await Axios({
url,
method,
data,
params,
});
return { data: result.data };
} catch (axiosError) {
const error = axiosError as AxiosError;
return {
error,
};
}
};
Useremo le API gratuite JSONPlaceholder in questo progetto.
In secondo luogo, dovremmo dire a rtk-query di utilizzare la nostra funzione di query personalizzata anziché l'API JS fetch. È semplicemente fattibile passando la nostra funzione a createApi .
// src/services/api.ts
export const apiService = createApi({
baseQuery: axiosBaseQuery(),
endpoints: () => ({}),
});
Infine, dobbiamo aggiungere apiService al redux store e aggiungere lo store alla nostra app:
// src/store/store.ts
export const store = configureStore({
reducer: {
[apiService.reducerPath]: apiService.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(apiService.middleware),
});
// src/main.tsx
<Provider store={store}>
<App />
</Provider>
Costruire il nostro primo servizio
Iniziamo con l'endpoint GET per recuperare l'elenco dei post dal server. Possiamo semplicemente utilizzare l'API injectEndpoint da rtk-query, per creare i nostri endpoint e aggiungerli al nostro livello di servizio di base.
// src/services/posts.ts
// Interface of JSONPlaceholder posts
export interface Post {
id: number;
userId: number;
title: string;
body: string;
}
export const postService = apiService.injectEndpoints({
endpoints: (build) => ({
// query<ResultType, QueryArg>
getPosts: build.query<Post[], null>({
query: () => ({ method: "GET", url: "posts" }),
}),
}),
});
// Auto-generated hooks
export const { useGetPostsQuery } = postService;
Quindi, rtk-query crea degli hook per recuperare facilmente queste query. Puoi passare più impostazioni ai tuoi costruttori di query come transformResponse che non trattiamo perché non rientrano nell'ambito di questo articolo.
Usiamo il nostro primo servizio
Ora è il momento di utilizzare il nostro servizio. rtk-query ha generato l'hook useGetPostsQuery per noi. Questo hook restituisce un oggetto costituito da alcuni valori utili da utilizzare. Come lo stato di caricamento, l'errore, i dati restituiti e la funzione di recupero.
- Stato di caricamento: sarà vero quando eseguiremo questa query nel nostro componente.
- Oggetto errore: se la nostra query fallisce, verrà restituito un oggetto errore, altrimenti è null .
- data: I nostri dati restituiti. È nullo finché la nostra query non viene eseguita correttamente .
- funzione refetch: possiamo usare questa funzione per rieseguire la query ogni volta che ne abbiamo bisogno. Ad esempio, nel caso in cui desideriamo avere un pulsante "Riprova" o aggiorna.
// src/components/PostList.tsx
const PostList: React.FC<unknown> = () => {
const { data: posts, isLoading, error, refetch } = useGetPostsQuery(null);
if (isLoading) {
return <div>Loading posts...</div>;
}
if (error) {
return <ErrorBanner error={error as AxiosError} refetch={refetch} />;
}
return (
<div>
<h2>Posts</h2>
<div>
{posts?.map((post) => (
<div className="postItem">
<h4>{post.title}</h4>
<p>{post.body}</p>
</div>
))}
</div>
</div>
);
};
export default PostList;
Per andare oltre, copriamo anche una query di mutazione. Vogliamo creare un post utilizzando un modulo che ottiene un titolo e un corpo dagli utenti. Iniziamo con la query stessa:
// src/services/posts.ts
export interface CreatePostDto {
title: string;
body: string;
}
export const postService = apiService.injectEndpoints({
endpoints: (build) => ({
// query<ResultType, QueryArg>
getPosts: build.query<Post[], null>({
query: () => ({ method: "GET", url: "posts" }),
}),
// We use mutation for POST endpoints
createPost: build.mutation<Post, CreatePostDto>({
query: (data) => ({
method: "POST",
url: "posts",
// We pass static userId to simplify this part
data: { userId: 1, ...data },
}),
}),
}),
});
// Auto-generated hooks
export const { useGetPostsQuery, useCreatePostMutation } = postService;
- Poiché vogliamo aggiungere alcuni dati con il metodo POST , usiamo build.mutation invece di build.query .
- Abbiamo specificato una nuova interfaccia per gli argomenti del nostro endpoint e passato i dati corrispondenti alla nostra richiesta axios.
// src/components/PostForm.tsx
const PostForm: React.FC<unknown> = () => {
const [title, setTitle] = useState<string>("");
const [body, setBody] = useState<string>("");
const [createPost, { isLoading }] = useCreatePostMutation();
const submitForm = async (e: FormEvent) => {
e.preventDefault();
try {
await createPost({ title, body });
} catch (e) {
console.log(e);
}
};
return (
<form onSubmit={submitForm}>
<input
name="title"
type="text"
placeholder="Title"
value={title}
onChange={(e) => setTitle(e.currentTarget.value)}
/>
<textarea
name="body"
placeholder="Body..."
rows={5}
value={body}
onChange={(e) => setBody(e.currentTarget.value)}
/>
<input
type="submit"
value={isLoading ? "Wait..." : "Submit"}
disabled={isLoading}
/>
</form>
);
};
export default PostForm;
Avvolgetelo
Abbiamo coperto i concetti di base più importanti di rtk-query. Abbiamo visto come possiamo creare i nostri servizi ed endpoint in modo modulare e come utilizzare fantastici hook generati automaticamente nei nostri componenti. Successivamente, pubblicherò articoli di follow-up che spiegheranno funzionalità e concetti più avanzati di rtk-query come la memorizzazione nella cache , il recupero della configurazione , la trasformazione dei dati, ecc.
La base di codice completa di tutto ciò che abbiamo trattato è pubblicata in questo repository e distribuita in questa pagina .
Se hai consigli o suggerimenti, sentiti libero di chiedermelo tramite la mia posta privata o aggiungi commenti e se ti è piaciuto questo articolo, non dimenticare di applaudire!
Altri contenuti su PlainEnglish.io .
Iscriviti alla nostra newsletter settimanale gratuita . Seguici su Twitter , LinkedIn , YouTube e Discord .
Ti interessa scalare l'avvio del tuo software ? Scopri Circuito .

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































