react-query系列一——基础及useQuery使用

2022-11-04  本文已影响0人  翔子丶

为什么要写这篇文章

  1. 公司业务使用react-query,但目前只停留在“能用”的阶段,离真正会用并且灵活使用API还有很长距离

react-query介绍

react-query是React数据获取(date-fetch)库,在使用Hooks写组件时,发起异步请求时,不仅需要管理请求状态,而且还需要处理异步数据,为此要多写几个useState/useEffect来控制。

而react-query也是一个Hooks库,使用很少的代码完成对服务端的状态管理,而且大多数情况下使用查询useQuery和修改useMutation就可以了

我们知道redux可以轻松的管理客户端状态,但并不适合处理异步和服务端状态,服务端状态有以下比较复杂的点:

而react-query正是为此而生,可以方便的管理服务端的状态

安装

# use npm
npm i react-query
# use yarn
yarn add react-query

使用

  1. 在App.tsx中创建全局实例client,并通过QueryClientProviderclient传递下去,用于管理所有请求

    import './App.css'
     import {
       QueryClient,
       QueryClientProvider,
     } from 'react-query'
     import { ReactQueryDevtools } from 'react-query/devtools';
     import Demo1 from './components/Demo1'
    
     // 创建一个 client
     const queryClient = new QueryClient()
     function App() {
       return (
         // 提供client
         <QueryClientProvider client={queryClient}>
           {/* 添加devtools */}
           {process.env.NODE_ENV === 'development' ? (
             <ReactQueryDevtools initialIsOpen={false} position='bottom-right' />
           ) : (
             ''
           )}
           <Demo1 />
         </QueryClientProvider>
       )
     }
    
     export default App
    
  2. 在组件中使用useQuery和useMutation,通过useQueryClient获取到全局QueryClient实例,调用api管理react-query的请求,如queryClient.invalidateQueries('posts')

     import axios from 'axios';
     import { useMutation, useQuery, useQueryClient } from 'react-query';
    
     type dataType = {
       id: string
       title: string
     }
     const Demo1 = () => {
       // 访问App QueryClientProvider提供的client 
       const queryClient = useQueryClient();
       const query = useQuery('posts', () => axios.get('https://jsonplaceholder.typicode.com/posts'))
       console.log(query);
       const { data, isLoading, isError } = query;
    
       const { mutate } = useMutation(() => axios.delete('https://jsonplaceholder.typicode.com/posts/1'), {
         onSuccess: () => {
           // 错误处理和刷新
           queryClient.invalidateQueries('posts')
         },
       })
       
       if (isError) {
         return <div>error</div>;
       }
       if (isLoading) {
         return <div>loading</div>;
       }
       
       return (
         <>
           <button
             onClick={() => {
               mutate()
             }}
           >
             Delete
           </button>
         <ul>
           {(data?.data as unknown as dataType[])?.map(d => <li key={d.id}>{d.title}</li>)}
         </ul>
         </>
       )
     }
    
     export default Demo1
    
    useQuery-query.jpg

示例:

import {
  useQuery,
  useMutation,
  useQueryClient,
  QueryClient,
  QueryClientProvider,
} from 'react-query'
import { getTodos, postTodo } from '../my-api'

// 创建一个 client
const queryClient = new QueryClient()

function App() {
  return (
    // 提供 client 至 App
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  )
}

function Todos() {
  // 访问 client
  const queryClient = useQueryClient()

  // 查询
  const query = useQuery('todos', getTodos)

  // 修改
  const mutation = useMutation(postTodo, {
    onSuccess: () => {
      // 错误处理和刷新
      queryClient.invalidateQueries('todos')
    },
  })

  return (
    <div>
      <ul>
        {query.data.map((todo) => (
          <li key={todo.id}>{todo.title}</li>
        ))}
      </ul>

      <button
        onClick={() => {
          mutation.mutate({
            id: Date.now(),
            title: 'Do Laundry',
          })
        }}
      >
        Add Todo
      </button>
    </div>
  )
}

render(<App />, document.getElementById('root'))

重要知识点

useQuery('posts', axios => ('https://jsonplaceholder.typicode.com/posts'), {
  select: ({ data }) => {
    return data.data;
  },
  cacheTime: Infinity,
  staleTime: Infinity,
});

通过devTools可以看到此时数据是fresh状态


useQuery-alsteTime.jpg

这时候页面上的所有相同query-keys的请求都会被缓存起来,想要重新请求就需要清空缓存

queryClient.invalidateQueries('todos');

可以看到此时["post", 3]["post", 2]是inactive状态,过设定的cacheTime后会被清除

参考资料

github仓库

上一篇 下一篇

猜你喜欢

热点阅读