FizzBuzz ボタンを作りながら React Hooks を学んでいきます。
目次はこちら。
FizzBuzz ボタンを整理する
前回、クラスコンポーネントと state を使って FizzBuzz ボタンを作りました。
今回は前回作ったものを整理して、ファイルを分割します。
具体的には
-
FizzBuzz
を状態管理部分と表示部分に分離してそれぞれ別ファイルに - 関数
fizzBuzz
も別ファイルに
していきます。
まだ Hooks は出てきません。
FizzBuzz
を別ファイルに切り出すので、App.tsx
は以下のようにシンプルになります。
App.tsx
import React from 'react';
import FizzBuzz from './FizzBuzz';
const App: React.FC = () => {
return <FizzBuzz initialCount={0} />;
};
export default App;
FizzBuzz.tsx
はこんな感じ。
表示部分を FizzBuzzView
として、別ファイルに切り出しました。
また、メッセージの作成部分 fizzBuzz
も別ファイルに切り出しました。
FizzBuzz.tsx
import React from 'react';
import FizzBuzzView from './FizzBuzzView';
import { fizzBuzz } from './common';
type Props = {
// props で count の初期値を受け取る
initialCount: number;
};
type State = {
// 状態として count を持つ
count: number;
};
// クラスコンポーネントで FizzBuzz ボタンを作る
class FizzBuzz extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
count: props.initialCount,
};
}
// マウントされたときの処理
componentDidMount() {
console.log('mount');
}
// アンマウントされたときの処理
componentWillUnmount() {
console.log('unmount');
}
// +1 ボタンを押すと count をインクリメントする
plus1 = () => this.setState(({ count }) => ({ count: count + 1 }));
// clear ボタンを押すと count をリセットする
clear = () => {
const { initialCount } = this.props;
this.setState({ count: initialCount });
};
render() {
console.log('render');
const { count } = this.state;
const { plus1, clear } = this;
const message = fizzBuzz(count);
return (
<FizzBuzzView
count={count}
message={message}
plus1={plus1}
clear={clear}
/>
);
}
}
export default FizzBuzz;
FizzBuzz の表示部分です。
値(count)とメッセージ(message)、ボタンを押したときの処理(plus1, clear)を props で受け取ります。
state を使わないので、関数コンポーネントで実装します。
FizzBuzzView.tsx
import React from 'react';
type Props = {
count: number;
message: string;
plus1: () => void;
clear: () => void;
};
const FizzBuzzView: React.FC<Props> = React.memo(
({ count, message, plus1, clear }: Props) => (
<div>
<div>{`${count} ${message}`}</div>
<div>
<button type="button" onClick={plus1}>
+1
</button>
<button type="button" onClick={clear}>
clear
</button>
</div>
</div>
)
);
export default FizzBuzzView;
fizzBuzz
は React と無関係な純粋な関数ですので、ファイルの拡張子は .tsx
ではなく .ts
にしておきます。
common.ts
// count の値に応じて fizzBuzz メッセージを返す
export const fizzBuzz = (count: number) => {
if (count === 0) {
return '';
}
if (count % 3 === 0 && count % 5 === 0) {
return 'FizzBuzz';
}
if (count % 3 === 0) {
return 'Fizz';
}
if (count % 5 === 0) {
return 'Buzz';
}
return '';
};
今回作成したソースコードはこちら。
次回は FizzBuzz ボタンの動作をわかりやすくするために App を少し改造します。