react-query: 网络请求库

一个好用的 react-query 库
更新于: 2024-01-18 07:26:44

关键词

nx.$mutation/nx.$query/nx.$client

services
	queries

使用

/* eslint-disable jsx-a11y/anchor-is-valid */
import React from 'react'
import ReactDOM from 'react-dom/client'
import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import axios from 'axios'

const queryClient = new QueryClient()

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Example />
    </QueryClientProvider>
  )
}

function Example() {
  const { isPending, error, data, isFetching } = useQuery({
    queryKey: ['repoData'],
    queryFn: () =>
      axios
        .get('https://api.github.com/repos/tannerlinsley/react-query')
        .then((res) => res.data),
  })

  if (isPending) return 'Loading...'

  if (error) return 'An error has occurred: ' + error.message

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{' '}
      <strong>✨ {data.stargazers_count}</strong>{' '}
      <strong>🍴 {data.forks_count}</strong>
      <div>{isFetching ? 'Updating...' : ''}</div>
      <ReactQueryDevtools initialIsOpen />
    </div>
  )
}

const rootElement = document.getElementById('root')
ReactDOM.createRoot(rootElement).render(<App />)

我的API

项目中使用 nx.$api来调用,项目中的 nx.$client 是 queryClient 实例。

export default {
  request: ['/admin', 'json'],
  items: [
    {
      items: {
        posts_index: ['get', '/posts'],
        posts_create: ['post', '/posts'],
        posts_show: ['get', '/posts/{id}'],
        posts_update: ['put', '/posts/{id}'],
        posts_destroy: ['delete', '/posts/{id}'],
      },
    },
  ],
};

cheatsheet

功能代码
posts 列表
function Example() {
  const { isPending, error, data, isFetching } = useQuery({
    queryKey: ['posts'],
    queryFn: nx.$api.posts_index
  });

  if (isPending) return 'Loading...';
  if (error) return 'An error has occurred: ' + error.message;

  // 省略 10000 行代码
}
posts 详情
function Example() {
  const { id, setPostId } = useParams();
  const { isPending, error, data, isFetching } = useQuery({
    queryKey: ['posts', id],
    queryFn: (id) => nx.$api.posts_index({ id })
  });
  // 省略 10000 行代码
}
posts 更新
function Example() {
  const { id, setPostId } = useParams();
  const { isPending, error, data, mutate, mutateAsync, isFetching } = useMutation({
    mutationKey: ['post', id],
    mutationFn: nx.$api.posts_update,
    onSuccess: () => {
      nx.$client.invalidateQueries(['posts']);
    }
  });
  // 省略 10000 行代码
}

// 调用
mutateAsync(payload);
posts 创建
function Example() {
  // posts create + refresh list
  const { isPending, error, data, isFetching } = useMutation({
    mutationKey: 'posts_create',
    mutationFn: nx.$api.posts_create,
    onSuccess: () => {
      nx.$client.invalidateQueries(['posts']);
    }
  });
  // 省略 10000 行代码
}
创建有返回(entity)
function Example() {
  // posts create + refresh list
  const { isPending, error, data, isFetching } = useMutation({
    mutationKey: 'posts_create',
    mutationFn: nx.$api.posts_create,
    onMutate: (variables) => {
      // Cancel any outgoing refetches (so they don't overwrite our optimistic update)
      queryClient.cancelQueries('posts');

      // Snapshot the previous value
      const previousPosts = queryClient.getQueryData('posts');

      // Optimistically update to the new value
      queryClient.setQueryData('posts', (old) => [
        ...old,
        { id: uuid(), title: variables.title }
      ]);

      // Return the snapshotted value
      return () => queryClient.setQueryData('posts', previousPosts);
    },
    onSuccess: () => {
      nx.$client.invalidateQueries(['posts']);
    }
  });
  // 省略 10000 行代码
}
多个 mutate 操作
const mutation = useMutation(updateArticle);

const articlesWithMutation = articles.map(article =>
  mutation.mutateAsync(article.id, 'New Title'),
);

try {
  await Promise.all(articlesWithMutation);
} catch (error) {
  console.log('An error has occured: ', error);
}

参考