Help us understand the problem. What is going on with this article?

react-fetching-library で Suspense 使ってみた。

最近ReactでAPIからデータフェッチする際にuseEffectを使っていましたが、
これを読んだあと、これからはSuspenseを積極的に使っていこうと思い立ちました。
https://overreacted.io/ja/a-complete-guide-to-useeffect/

そんな自分にタイムリーなパッケージ、4日前(投稿日現在)に出来立てホヤホヤの
react-fetching-libraryを発見。
早速使ってみたいと思います!
image.png
https://marcin-piela.github.io/react-fetching-library/#/?id=usesuspensequery

Suspense使用前

ポートフォリオに投稿したQiitaの記事を載せるために、こんな感じで実装していました。
レンダリングしている内容は省略します🙇‍♂️

App.js
import React from 'react'
import Writing from 'sections/Writing'

export default () => {
  return (
    <div>
      <Writing />
    </div>
  )
}
sections/Writing.js
import React, { useState, useEffect } from 'react'
import { fetchQiitaArticles } from 'lib/api'

export default () => {
  const [articles, setArticles] = useState([])

  useEffect(() => {
    const handleGetArticles = response => {
      setArticles(response)
    }
    fetchQiitaArticles({ handleGetArticles })
  }, [])

  return (
    // fetchしたarticlesを使ってレンダリング
  )
}
lib/api.js
export const fetchQiitaArticles = async props => {
  const { handleGetArticles } = props
  await fetchGet({
    auth: process.env.REACT_APP_QIITA_AUTH,
    url: 'https://qiita.com/api/v2/authenticated_user/items',
    successAction: handleGetArticles,
  })
}

const fetchGet = async props => {
  const { auth, url, successAction, failureAction } = props

  return await fetch(url, {
    headers: {
      Authorization: `Bearer ${auth}`,
    },
  })
    .then(response => response.json())
    .then(responseJson => {
      // console.log(responseJson)
      if (successAction) {
        successAction(responseJson)
      }
    })
    .catch(error => {
      // console.error(error)
      if (failureAction) {
        failureAction()
      }
    })
}

セットアップ

まずは react-fetching-libraryをインストールします。

$ yarn add react-fetching-library

続いてClientの作成します。
とりあえず今回はオプションなし。

api/Client.js
import { createClient } from 'react-fetching-library'
export const Client = createClient()

そして<ClientContextProvider>でAppを囲います。

App.js
import React from 'react'
import { ClientContextProvider } from 'react-fetching-library'
import { Client } from 'api/Client'
import Writing from 'sections/Writing'

export default () => {
  return (
    <ClientContextProvider client={Client}>
      <Writing />
    </ClientContextProvider>
  )
}

これで、react-fetching-libraryの機能が使用可能になりました!

fetchの用意

react-fetching-libraryで使用するGETメソッドを作成します。

api/fetchMyQiitaArticles.js
export const fetchMyQiitaArticles = {
  method: 'GET',
  endpoint: 'https://qiita.com/api/v2/authenticated_user/items',
  headers: {
    Authorization: `Bearer ${process.env.REACT_APP_QIITA_AUTH}`,
  },
}

コンポーネントのラップ

useEffectを廃止してWritingContainerでラップします。
その際、useSuspenseQueryを使ってデータフェッチを行うようにします。

container/WiritingContainer.js
import React from 'react'
import { useSuspenseQuery } from 'react-fetching-library'
import { fetchMyQiitaArticles } from 'api/fetchMyQiitaArticles'
import Writing from 'sections/Writing'

export default () => {
  const { payload, error, query } = useSuspenseQuery(fetchMyQiitaArticles)

  return <Writing error={error} articles={payload} />
}
sections/Writing.js
import React, { useState, useEffect } from 'react'
import { fetchQiitaArticles } from 'lib/api'

export default props => {
  const { articles, error } = props

  return (
    // fetchしたarticlesを使ってレンダリング
  )
}

Suspenseを使う!

App.js
import React, { Suspense } from 'react'
import { ClientContextProvider } from 'react-fetching-library'
import { Client } from 'api/Client'
import WritingContainer from 'container/WritingContainer'

export default () => {
  return (
    <ClientContextProvider client={Client}>
      <Suspense fallback={<p>Loading ...</p>}>
        <WritingContainer />
      </Suspense>
    </ClientContextProvider>
  )
}

かなりアバウトになりましたが、
これでSuspenseを使ったデータフェッチができました 🎉

おわりに

とりあえず自分はuseEffectを使わずにデータフェッチができるようになりました。
Suspense界隈のリリース情報はしっかり追っていきたいですね。
あとreact-fetching-libraryの公式DocがTypeScriptで説明されていたので、
TypeScriptでの開発のモチベーションになりそうです。

参考

https://marcin-piela.github.io/react-fetching-library/#/?id=usage

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした