Flowによるreactの静的型付け
今までPropTypesやTypeScriptによる静的型付けを述べてきたが、今回はFlowを用いた実装をしてみる。
次のようなディレクトリ構造で、5つ星評価のUI実装を考える。
. ├── Stars.css └── Stars.js
インストール
インストール方法は公式ドキュメントに丁寧に書いてあるので割愛。
セットアップ
npm install --save-dev flow-bin
package.json
に次のnpm scriptsを追加。
"scripts": { "flow": "flow" }
まず最初にnpm run flow init
を実行して.flowconfig
を生成する。
それ以降は適宜npm run flow
を実行しながら開発を進めていく。他のnpm scriptsと合わせて実行したり、nodemonなどと組み合わせたりすると便利そう。
実装
font-awesomeのアイコンを使いたいので、react-icons
をインストールする。
npm install react-icons
Stars.css
.stars { display: inline-flex; } .stars .star:not(:first-of-type) { margin-left: 3px; } .star { background-color: transparent; border: none; cursor: pointer; outline: none; padding: 0; appearance: none; }
Stars.js
// @flow import * as React from 'react'; import { FaStar } from 'react-icons/fa'; import './Stars.css'; type Props = { rating?: number, }; type State = { rating: number, colorArray: Array<string>, }; class Stars extends React.Component<Props, State> { constructor(props) { super(props); this.defaultColor = '#d7d7d7'; this.selectedColor = '#55c500'; this.state = { rating: this.props.rating, colorArray: Array(5) .fill() .map(() => this.defaultColor), }; } componentDidMount() { this.updateColor(this.state.rating - 1); } updateColor = index => { const { colorArray } = this.state; for (let i = 0; i <= index; i += 1) { colorArray[i] = this.selectedColor; } for (let j = index + 1; j < 5; j += 1) { colorArray[j] = this.defaultColor; } this.setState({ colorArray, }); }; render() { const { colorArray } = this.state; return ( <div className="stars"> {colorArray.map((c, i) => ( <button type="button" className="star" onClick={() => this.updateColor(i)} key={i} > <FaStar color={c} size={24} /> </button> ))} </div> ); } } Stars.defaultProps = { rating: 3, }; export default Stars;
@flow
と先頭に記述するファイルが、型バリデーションの対象となる。
VSCodeを使用している場合、下記のエクステンションを入れれば、fcc
で一発展開してくれる。
(Class component with flow types skeleton)
type Props
でpropsのアノテーション、type State
でstateのアノテーションができる。defaultProps
などと組み合わせて適宜使う。
TypeScriptよりは簡単に実装できるが、TSのようにType Inferenceが効いていないのではないかと思われる。
あとは、とにかくドキュメントが簡潔でわかりやすいところがよい。
後書き
軽い実装の練習がてらFlowを試してみたが、今の世の中のトレンドとしては圧倒的にTypeScriptなので、学ぶならやっぱりTypeScriptの方がベター。