avatar

Tetsuya Ohira's Blog

Software Developer in Japan 🚀

React NativeアプリケーションにおけるuseSWRとAxiosの効果的な使用

2023-12-03

仕事でReact NativeプロジェクトのAPI処理を実装する機会があった。 その際、useSWRを使ってデータ取得を行うカスタムフックを作成したので実装を紹介する。

プロジェクトのディレクトリ構成

/src /components /... # コンポーネントファイル /hooks /useFetchData.ts # カスタムSWRフック /providers /SWRConfigProvider.tsx # SWR設定プロバイダー /utils /axiosInstance.ts # axiosの共通設定 /fetcher.ts # SWRのfetcher App.tsx # アプリケーションのエントリポイント

useSWRのカスタムフックの作成

  • React Nativeアプリケーションでデータフェッチを効率化するために、useSWRを使用したカスタムフックを作成した。
  • このフックは、APIリクエストを簡単に行い、データのローディング状態やエラー状態を管理する機能を提供する。
  • useSWRをつかうので当然ながらCache機能も備えている。
  • また、このフックはカスタムオプションを受け取るため、特定のコンポーネントでのリクエストの挙動を柔軟にカスタマイズできる。
// /hooks/useFetchData.ts import useSWR, { SWRConfiguration } from 'swr' import fetcher from '@/utils/fetcher' function useFetchData<T>(url: string, options?: SWRConfiguration) { const { data, error, isValidating, mutate } = useSWR<T>(url, () => fetcher<T>(url), { ...options }) return { data, isLoading: !error && !data, isError: error, isValidating, mutate } } export default useFetchData

SWRConfigProviderによる共通設定の適用

  • React Nativeの特性を考慮して、アプリケーション全体にわたるSWRの挙動をカスタマイズするために、SWRConfigProviderを導入した。
  • このプロバイダーを使用することで、アプリ特有のライフサイクルやネットワーク状態に応じたデータフェッチの挙動を一元的に管理できる。
  • initFocusは、アプリがフォアグラウンドに戻ったときに呼び出されるコールバック関数で、AppStateAPIを使用して実装している。
  • initReconnectは、ネットワークの接続状態が変わったときに呼び出されるコールバック関数、NetInfoAPIを使用して実装している。
// /providers/SWRConfigProvider.tsx import React from 'react' import { SWRConfig, SWRConfiguration } from 'swr' const swrConfiguration: SWRConfiguration = { provider: () => new Map(), isVisible: () => true, isOnline: () => true, initFocus: (callback: () => void) => { let appState = AppState.currentState const onAppStateChange = (nextAppState) => { if (appState.match(/inactive|background/) && nextAppState === 'active') { callback() } appState = nextAppState } const subscription = AppState.addEventListener('change', onAppStateChange) return () => subscription.remove() }, initReconnect: (callback: () => void) => { const unsubscribe = NetInfo.addEventListener((state) => { if (state.isConnected) { callback() } }) return () => unsubscribe() } } const SWRConfigProvider: React.FC = ({ children }) => { return ( <SWRConfig value = { swrConfiguration } > { children } </SWRConfig> ) } export default SWRConfigProvider

Axiosの共通設定とインターセプターの使用

  • APIリクエストの効率化と一貫性を高めるために、axiosの共通設定とインターセプターを導入した。
  • axios.createを使用してカスタマイズされたaxiosインスタンスを作成し、リクエストとレスポンスのインターセプターを通じて、共通のヘッダーやエラーハンドリングを実装している。
  • これにより、各APIリクエストでのコードの重複を減らし、エラー処理を一元管理できる。
// /utils/axiosInstance.ts import axios from 'axios' import * as process from 'process' const baseURL = process.env.API_BASE_URL || '' const axiosInstance = axios.create({ baseURL }) axiosInstance.interceptors.request.use(config => { const accessToken = 'accessToken' config.headers.Authorization = accessToken ? `Bearer ${accessToken}` : '' return config }) axiosInstance.interceptors.response.use( response => response, error => { // BagSnagなどのエラーハンドリングツールを使用する場合はここでエラーを送信 return Promise.reject(error) } ) export default axiosInstance
// /utils/fetcher.ts import axiosInstance from '@/utils/axiosInstance' const fetcher = async <T>(url: string): Promise<T> => { const response = await axiosInstance.get<T>(url) return response.data } export default fetcher

以上、React NativeアプリケーションでのuseSWRのカスタムフック作成、SWRConfigProviderの導入、およびaxiosの共通設定とインターセプターの使用について紹介した。

参考