Reactカスタムフックの可能性を感じる

公開日:2019-06-12
最終更新:2019-06-12

Reactカスタムフックの可能性を感じる

趣味でReactの勉強を始めて早ひと月。何か面白い機能は無いかなーとReact公式を眺めていたら、面白そうなものが目に入りました。
その名も「カスタムフック」。むしろ何故今まで気づかなかった。

というわけで、簡単に使い方をまとめてみます。

カスタムフックを使わない場合

例えば本の情報を保持する配列があるとして。

// modules/books.ts  
export interface book {  
  name: string,  
  author: string,  
  isbn13: string  
};  

const books: Array<book> = [{  
    name: "React.js&Next.js超入門",  
    author: "掌田 津耶乃",  
    isbn13: "978-4798056920",  
  }, {  
    name: "React開発 現場の教科書",  
    author: "石橋 啓太",  
    isbn13: "978-4839960490",  
  }, {  
    name: "Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門",  
    author: "Stoyan Stefanov",  
    isbn13: "978-4873117881",  
}];  

export default books;  

この配列から一つの要素を画面に表示するとします。
表示する要素はボタンで簡単に切り替えられるようにしましょう。

というわけで、出来上がったコードがこちら。

// App.tsx  
import React, { useState, useCallback } from 'react';  
import _ from 'lodash'  
import './App.css'  
import Button from '@material-ui/core/Button'  
import books from './modules/books'  

const App: React.FC = () => {  
  const [bookNum, setBookNum] = useState(0);  
  const book = books[bookNum];  

  return (  
    <div className="App">  

      <div className="buttons">  
        {_.range(books.length).map(n =>  
          <Button key={`button-${n}`} onClick={() => setBookNum(n)}>CHANGE: {n}</Button>  
        )}  
      </div>  

      <div className="book_info">  
        <p>タイトル:{book.name}</p>  
        <p>著者:{book.author}</p>  
        <p>ISBN-13:{book.isbn13}</p>  
      </div>  

    </div>  
  );  
}  

export default App;  

実際にはbuttonsbook_infoは別コンポーネントに切り出してるかもしれませんね。

ところでこのコード、いくつか気になるところがありませんか? 個人的にはbookNum周りがイケてないと思います。

カスタムフックを使った場合

というわけで、本題のカスタムフックに入っていきましょう。カスタムフックはユーザーが自由に作成することができ、かつ内部でReactが提供しているフックを利用することができる構文です。
早速カスタムフックを作ってみましょう。

// modules/books.ts  
import { useState, Dispatch, SetStateAction } from "react";  

export interface book {  
  name: string,  
  author: string,  
  isbn13: string  
};  

const books: Array<book> = [{  
    name: "React.js&Next.js超入門",  
    author: "掌田 津耶乃",  
    isbn13: "978-4798056920",  
  }, {  
    name: "React開発 現場の教科書",  
    author: "石橋 啓太",  
    isbn13: "978-4839960490",  
  }, {  
    name: "Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門",  
    author: "Stoyan Stefanov",  
    isbn13: "978-4873117881",  
}];  

export const useCurrentBook = (books: Array<book>): [book, number, Dispatch<SetStateAction<number>>] => {  
  const [bookNum, setBookNum] = useState(0);  

  return [books[bookNum], books.length, setBookNum];  
}  

export default books;  

関係するロジックをuseCurrentBookの中に閉じ込めました。これで利用する側からはbookNumというイケてない変数を消し去ることができます。必要があればsetBookNum等の名前も変えていいでしょう。
なお、カスタムフックにはuseから始まる関数名にしなければならないという規則があります。注意しましょう。

そして最終的なコードはこちら。

// App.tsx  
import React from 'react';  
import _ from 'lodash'  
import './App.css'  
import Button from '@material-ui/core/Button'  
import books, { useCurrentBook } from './modules/books'  

const App: React.FC = () => {  
  const [book, booksSize, setBookNum] = useCurrentBook(books);  

  return (  
    <div className="App">  

      <div className="buttons">  
        {_.range(booksSize).map(n =>  
          <Button key={`button-${n}`} onClick={() => setBookNum(n)}>CHANGE: {n}</Button>  
        )}  
      </div>  

      <div className="book_info">  
        <p>タイトル:{book.name}</p>  
        <p>著者:{book.author}</p>  
        <p>ISBN-13:{book.isbn13}</p>  
      </div>  

    </div>  
  );  
}  

export default App;  

実行してみても、動作に影響がないことがわかります。

このようにカスタムフックはフックを用いたロジックをモジュールとしてまとめることができます。
また、カスタムフックは呼び出される個所ごとにstateを生成するため、状態を共有することはありません。同一のロジックを用いていて、かつ別個のstateを管理したい場合にとても役に立つでしょう。そういう意味では今回の例は悪かったかもしれませんね。

まとめ

というわけで、カスタムフックの紹介でした。
モジュールの形式で切り出すのか、カスタムフックの形で切り出すのか、ロジックを整理してしっかり使い分けていきたいですね。

参考

React公式 カスタムフックの作成

記事が少しでもいいなと思ったらクラップを送ってみよう!
20
+1
だらだら更新していきたい技術ブログ

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする