23
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NRI OpenStandiaAdvent Calendar 2021

Day 17

React hooks+axiosを使ったAPIからデータ取得方法

Last updated at Posted at 2021-12-16

#はじめに

React hooksでHotPepper APIを叩いてデータを取得し画面表示~画面遷移を実装したので
React hooksとaxiosを使ったAPIデータの取得方法やGlobalStateを使ったデータ保持方法について紹介します。

対象

  • React初学者
  • React hooksについて知りたい方

React hooks

まずは、React hooksについて簡単に紹介します。
React hooksはReact 16.8から追加された機能で公式サイトでは、以下のように説明があります。

フック (hook) は React 16.8 で追加された新機能です。state などの React の機能を、クラスを書かずに使えるようになります。

React hooksの登場により、クラスコンポーネントでしか使えなかった機能が、関数コンポーネントでも使えるようになりました。

クラスコンポーネントと関数コンポーネント

そもそもなぜ関数コンポーネントの方がいいのかというところから説明します。簡単な例として、公式ドキュメントから「ボタンをクリックすると、カウンターの値が増える」ソースコードを関数コンポーネントとクラスコンポーネントで作成した例を示します。

クラスコンポーネントでの実装
import React from 'react';

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }
  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}


関数コンポーネントでの実装
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me </button>
    </div>
   
  );
}

この二つのコードを比べるとわかるように、関数コンポーネントを使用することで以下のメリットが挙げられます。

  • コード量の削減
  • 可読性の向上
  • thisを使用せず実装可能

さらに、従来の関数コンポーネントではstateを持つことができなかったのですが、React hooksの登場によりそれが可能となりました。
次に、今回はWebアプリ開発でよく使われるuseEffectuseContextuseReducerを使い実装したのでそれぞれについて紹介します。

useEffect

import { useEffect } from 'react';
useEffect(() => {
    // 実行処理
}, []));

useEffectは、クラスコンポーネントであるcomponentDidMountcomponentDidUpdatecomponentWillUnmount のメソッドの代わりに使用可能です。
useEffectを使うと、関数の実行をレンダリング後まで遅らせることができ、API通信やDOMの書き換えを関の処理などを関数コンポーネントで実装できます。
今回はuseEffect内にホットペッパーからAPIデータを取得する処理を実装しました。

useContext

親から子コンポーネント間でのデータ受け渡しを階層に関係なくデータを渡せる機能です。

context_image.png

上記の図のように従来はpropsによるバケツリレーをしていたが、
useContextを使うことでコンポーネントを超えて値を引き渡すことが可能です。

useReducer

現在のstateactionを受け取って、stateを更新し、新しいstateを返します。
useStateも同じことができますが、複雑な状態遷移を処理する場合はuseReducerを使います。
useEffectuseStateの違いについては以下の記事を参考にしてください。

GlobalStateでの管理

GlobalStateを作ることで、様々なコンポーネントからstateへのアクセスが可能となります。
コンポーネント単位でpropsを使用せずデータを管理しようとすると、Reduxが必要でしたが
useContextuseReducerを使うことでデータ管理が可能となりました。

import React,{createContext,useReducer} from 'react'

// initialStateの初期化
const initialState ={
    searchData: [],
    selected: {}
}

// reducerによるデータ管理
const reducer = (state,action) => {

    switch(action.type) {
        case 'SET_DATA':
            return {...state, searchData: action.payload.searchData}
        case 'SET_SELECTED':
            return {...state,selected: action.payload.selected}
        default:
            return state
    }
}

// globalStateを各コンポーネントで使用できるようにする。
export const Store = createContext({
    globalState: initialState,
    setGlobalState: () => null
})

//コンポーネントとして登録し、Providerでラップしデータを渡す。
//childernを受けているので、<Store.Provider>で全体を包むことで親要素を全て取得することができる。
export const StoreProvider = ({children}) => {
    const [globalState,setGlobalState] = useReducer(reducer,initialState)

    return (
        <Store.Provider value={{globalState,setGlobalState}}>{children}</Store.Provider>
    )
}

export default StoreProvider

GlobalStateを参照する際はuseContextを使います。

//StoreからGlobalStateを取り出す
 const { globalState,setGlobalState} = useContext(Store)

axiosを使ったAPI取得

axiosとはブラウザやnode.js上で動くPromiseベースのHTTPクライアントです。

axiosの導入

次のコマンドを実行してインストールします。

$ npm install axios --save

HotPepper API

HotPepper APIは株式会社リクルートが提供するAPIでホットペッパーグルメに使われています。APIの詳細については以下URLを参考にしてください。

HotPepper API取得部分

import axios from 'axios'

const KEY = 'HotpepperのAPIキー'

// axiosのインスタンス作成
const hotpepper = axios.create ({
    baseURL: 'http://webservice.recruit.co.jp/hotpepper/gourmet/v1'
})

export const fetchSearchData = async() =>{
    //大エリアコード=Z011(東京)のお店を検索
        return await hotpepper.get('',{
            params: {
                key:KEY,
                large_area:'Z011',
                format: 'json'  
             }
         })
    }
}

useEffect内でAPIを実行

useEffect内でAPI取得部分を実装したソースコードを以下に示します。

    useEffect(() =>{
        fetchSearchData().then((res) => {
            console.log(res)
        })
    },[])

APIを叩いたブラウザ画面にアクセスし、開発者ツールのコンソールを確認します。
resにHotpepper APIから取得したデータが入っていることがわかります。

hotpepperdata.png

GlobalstateにAPIデータが格納されているか確認

Facebook社から提供されている公式のReact用のデバッグツールであるReact Developer Toolsを利用し確認します。
Context.ProviderコンポーネントのGlobalstateにAPIデータが格納されていることがわかります。

スクリーンショット 2021-12-10 102829.png

最後に

今回は、初学者向けにReact hooksとは何か?からaxiosを使ったAPIデータの取得方法やAPIデータをGlobalStateで管理する方法について紹介しました。
Reactについて調べていると、ReduxReact hooksなど様々な用語や記事が出てくると思います。
下記記事にもあるように徐々にReduxからReact hooksが主流になるのではないかなと思います。
皆様もぜひReact hooksを活用してみてくださいね。

23
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?