iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
Modern Web

用Jest和Enzyme來寫React測試吧!!系列 第 28

【Day28】React Query 簡易說明及使用 (´∀`)

What's React Query !? React Query 是一個適合用於React Hook的Library,

它可以幫助我們取得、同步、更新跟緩存我們的遠端數據,且可以更好的處理Server端的states。

雖然說小菜鳥在上一篇有提到覺得React Query比React Redux好用,但其實這兩種是可以併存的,

只是React Query可以只透過幾個簡單的API就能幫我們處理cache及Server端的states。


原理

  • 透過Promise、Async、Await來處理異步數據

優點

  • 幫助我們減少複雜的代碼,用較少的React查詢邏輯來代替
  • 不用擔心如何連接新的Server States
  • 節省及提高效能
  • 可以處理麻煩的cache
  • 不用進行配置

重點

  • 查詢並渲染在畫面上的結果會在它們被resolved後立馬過期,只有再一次render或是被使用到時,會自動重新fetch,但我們可以透過設定staleTime來調整過期的時間 (預設為0)

      const {
            data,
            isLoading,
            isError,
            isSuccess,
          } = useQuery ('planets', fetchPlanets,{
            staleTime: 5000,
          })
    
  • 查詢的結果在Component unmount後仍然會被cached,GC 的預設時間是五分鐘,也就是五分鐘如果我們沒有用到,它們就掰掰了~ (可以設定cacheTime來設定它們被cache的時間)

      const {
            data,
            isLoading,
            isError,
            isSuccess,
          } = useQuery ('planets', fetchPlanets,{
            cacheTime: 5000,
          })
    
  • 過期的查詢會在使用者重整瀏覽器或重新聚焦於瀏覽器的時候或者重新連線的時候會重新fetch,但如果我們不想讓使用者透過這樣的方式重新fetch的話,可以透過React Query裡的Query Client 裡的兩個設定來關閉 (refetchOnWindowFocus & refetchOnReconnect)

    import { QueryClient, QueryClientProvider } from 'react-query'
    const queryClient = new QueryClient({
       defaultOptions: {
         queries: {
           refetchOnWindowFocus: false,
           refetchOnReconnect:false,
         },
       },
     })
    function App() {
      return (
        <QueryClientProvider client={queryClient} contextSharing={true}>
          <div className="App">
    
            <Planets/>
          </div>
        </QueryClientProvider>
      );
    }
    
  • 查詢如果失敗的話,會重試三次,當三次都失敗的時候才會顯示error,我們可以透過設定retry & retryDelay來調整

      const {
            data,
            isLoading,
            isError,
            isSuccess,
          } = useQuery ('planets', fetchPlanets,{
             retry: 10,
             retryDelay: 1000,
          })
    

簡易使用方式

  • 先創建一個Query Client 並鑲在我們的Component外層

    import { QueryClient, QueryClientProvider } from 'react-query'
    import Planets from './Planet';
    const queryClient = new QueryClient()
    function App() {
      return (
        <QueryClientProvider client={queryClient} contextSharing={true}>
          <div className="App">
    
            <Planets/>
          </div>
        </QueryClientProvider>
      );
    }
    
    export default App;
    
  • 在Component內建立一個函式變數,透過async/await的方式來fetch某個api

    const fetchPlanets = async (key,page) => {
        const res = await fetch(`https://swapi.dev/api/planets/?page=${page}`)
        return res.json()
      }
    
  • 接著將此函式變數帶入useQuery裡

    export default  function Planets() {
        const [page, setPage] = useState(1)
        const {
            data,
            isLoading,
            isError,
            isSuccess,
          } = useQuery ('planets', fetchPlanets,{
            keepPreviousData: true,
          })
    
    
      return (
        <div>
          <h2>Planets</h2>
          <button onClick={() => setPage((prevPage) => Math.max(prevPage - 1, 1))}> 
            Previous Page
          </button>
          <div>{page}</div>
          <button
            onClick={() =>
              setPage((prevPage) =>
                !data || !data.next ? prevPage : prevPage + 1
              )
            }
          >
            Next Page
          </button>
          {isLoading && <div>Loading...</div>}
          {isError && <div>Fetching error</div>}
          {isSuccess &&
            data.results.map((planet) => {
              return <Planet planet={planet} key={planet.name} />
            })}
        </div>
      );
    }
    

上述,是針對React Query 的簡單說明~ 希望還算清楚இдஇ

下一篇,小菜鳥要來分享自己在使用React時候踩過的一些小地雷 !

快要接近尾聲了 !! 加油呀 ~


上一篇
【Day27】React Redux 原理及應用方法簡介 ╰(°ㅂ°)╯
下一篇
【Day29】從小菜鳥使用React到現在踩到的地雷經驗談 (ᗒᗣᗕ)՞
系列文
用Jest和Enzyme來寫React測試吧!!30

尚未有邦友留言

立即登入留言